[SQL study notes] Column to row and query results to JSON

Foreword

When grouping queries, columns that are not set as a grouping need to be combined using an aggregation function. Generally, it is sufficient to use the aggregation function provided by each database, and some special usage scenarios may require manual multi-row data in one column. Turn into lines to achieve an effect similar to the aggregation function.

Case

There are two tables as follows: Class (class), Student (student), the relationship is as
ER relationship diagram of the two tables
follows: the data in the two tables is as follows: the
Table data graph
query code for the connection of the two tables is as follows:

--先查看连接的结果
SELECT
	*
FROM Class C
LEFT JOIN Student S ON S.ClassAID = C.AID

The results of the two table join query are as follows:
Connection query result graph
on this basis, adding group statistics can get how many students are in each class. The
code is as follows:

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

The results are as follows:
Statistics of students in each class

The key is coming

On the basis of querying the number of students in each class, at the same time query the list of student names in each class.
If the query is written like this:

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

It will prompt a non-aggregation error (you cannot combine multiple rows of student names into one row of data to display):
Unaggregated error
If you do not use group query, you cannot count the number of students, and the information in the previous columns will be displayed repeatedly, such query results will make the background It is difficult for the caller to handle:

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

The results are as follows: In
Repeated display and cannot count the number of students
this case, when using a group query to count the number of students, multiple rows of data in the student list need to be aggregated into one row for display. The built-in aggregation function of the database is not enough. At this time, you can consider multi-line student names The information is converted into json and displayed in a line.

solve

code show as below:

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

The execution results are as follows:
Grouping plus manual json aggregation results
At this point, the notes are over.
In order to avoid unsightly NULL in the result (mainly because JAVA reception is not easy to handle), slightly optimize the above code as follows:

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

Optimized query results

Other tips you can skip

When using FOR JSON AUTO to convert the query result to JSON, if there are ambiguity characters in the result (for example, I encountered a slash in the query result: /, an escape character (backslash) will be automatically added to the converted JSON: \), Here is a special note on the processing method found at the time:
Handling extra transfer characters that may result from transferring to JSON
supplementary records:
REPLACE (parameter one, parameter two, parameter three)
parameter one: the original string (mother string)
parameter two: the search to be replaced The string (substring)
parameter three: I want to replace the string
as in the above code, I look for '\' in the json string and replace the '\' with '' (the single quotes have nothing , Without spaces)

Published 23 original articles · Like1 · Visits 20,000+

Guess you like

Origin blog.csdn.net/shenjie_xsj/article/details/105229649