Prefácio
Ao agrupar consultas, as colunas que não são definidas como um agrupamento precisam ser combinadas usando uma função de agregação.Em geral, é suficiente usar a função de agregação fornecida por cada banco de dados, e alguns cenários de uso especial podem exigir dados manuais de várias linhas em uma coluna. Transforme em linhas para obter um efeito semelhante à função de agregação.
Case
Existem duas tabelas da seguinte forma: Classe (classe), Aluno (aluno), o relacionamento é o
seguinte: os dados nas duas tabelas são os seguintes: o
código de consulta para a conexão das duas tabelas é o seguinte:
--先查看连接的结果
SELECT
*
FROM Class C
LEFT JOIN Student S ON S.ClassAID = C.AID
Os resultados da consulta de junção de duas tabelas são os seguintes:
nesta base, a adição de estatísticas de grupo pode obter quantos alunos há em cada classe.O
código é o seguinte:
SELECT
[班级AID] = C.AID
,[班级名称] = C.Name
,[班主任] = C.TeacherHeadName
,[学生数量] = ISNULL(COUNT(S.AID),0)
FROM Class C
LEFT JOIN Student S ON S.ClassAID = C.AID
GROUP BY C.AID,C.Name,C.TeacherHeadName
Os resultados são os seguintes:
A chave está chegando
Com base na consulta do número de alunos em cada turma, consulte ao mesmo tempo a lista de nomes de alunos em cada turma.
Se a consulta for escrita assim:
SELECT
[班级AID] = C.AID
,[班级名称] = C.Name
,[班主任] = C.TeacherHeadName
,[学生数量] = ISNULL(COUNT(S.AID),0)
,[学生们] = S.Name
FROM Class C
LEFT JOIN Student S ON S.ClassAID = C.AID
GROUP BY C.AID,C.Name,C.TeacherHeadName
Ele solicitará um erro de não agregação (você não pode combinar várias linhas de nomes de alunos em uma linha de dados a serem exibidas):
Se você não usar a consulta de grupo, não poderá contar o número de alunos, e as informações nas colunas anteriores serão exibidas repetidamente, os resultados dessa consulta criarão o plano de fundo É difícil para o chamador lidar com:
SELECT
[班级AID] = C.AID
,[班级名称] = C.Name
,[班主任] = C.TeacherHeadName
--,[学生数量] = ISNULL(COUNT(S.AID),0)
,[学生们] = S.Name
FROM Class C
LEFT JOIN Student S ON S.ClassAID = C.AID
--GROUP BY C.AID,C.Name,C.TeacherHeadName
Os resultados são os seguintes: Nesse
caso, ao usar uma consulta de grupo para contar o número de alunos, várias linhas de dados na lista de alunos precisam ser agregadas em uma linha para exibição.A função de agregação integrada do banco de dados não é suficiente.No momento, você pode considerar nomes de alunos com várias linhas As informações são convertidas em json e exibidas em uma linha.
Resolver
O código é o seguinte:
SELECT
[班级AID] = C.AID
,[班级名称] = C.Name
,[班主任] = C.TeacherHeadName
,[学生数量] = ISNULL(COUNT(S.AID),0)
,[学生们] =
(
SELECT
[学生姓名] = CONVERT(nvarchar(3),InsideS.Name)
FROM Student InsideS
WHERE InsideS.ClassAID = C.AID
FOR JSON AUTO
)
FROM Class C
LEFT JOIN Student S ON S.ClassAID = C.AID
GROUP BY C.AID,C.Name,C.TeacherHeadName
Os resultados da execução são os seguintes:
Neste ponto, as notas terminaram.
Para evitar NULL feio no resultado (principalmente porque a recepção JAVA não é fácil de manusear), otimize levemente o código acima da seguinte maneira:
SELECT
[班级AID] = C.AID
,[班级名称] = C.Name
,[班主任] = C.TeacherHeadName
,[学生数量] = ISNULL(COUNT(S.AID),0)
,[学生们] = ISNULL--判断:若返回的json字符串为NULL,则转成指定的空字符串
(
(
SELECT
[学生姓名] = CONVERT(nvarchar(3),InsideS.Name)
FROM Student InsideS
WHERE InsideS.ClassAID = C.AID
FOR JSON AUTO
)
,
''--长度为0的字符串(空的字符串)
)
FROM Class C
LEFT JOIN Student S ON S.ClassAID = C.AID
GROUP BY C.AID,C.Name,C.TeacherHeadName
Outras dicas que você pode pular
Ao usar FOR JSON AUTO para converter o resultado da consulta em JSON, se houver caracteres de ambiguidade no resultado (por exemplo, encontrei uma barra no resultado da consulta: /, um caractere de escape (barra invertida) será automaticamente adicionado ao JSON convertido: \), Aqui está uma observação especial sobre o método de processamento encontrado no momento:
registros suplementares:
REPLACE (parâmetro um, parâmetro dois, parâmetro três)
parâmetro um: a sequência original (sequência mãe)
parâmetro dois: a pesquisa a ser substituída O
parâmetro string (substring) três: quero substituir a string
como no código acima, procuro por '\' na string json e substituo o '\' por '' (as aspas simples não têm nada , Sem espaços)