我是SQL Server的新手,曾经与MYSQL一起工作,并尝试使用Group By从表中获取记录。
表结构如下:
SELECT S1.ID,S1.Template_ID,S1.Assigned_By,S1.Assignees,S1.Active FROM "Schedule" AS S1;
输出:
ID Template_ID Assigned_By Assignees Active
2 25 1 3 1
3 25 5 6 1
6 26 5 6 1
我需要使用下面的Group By语句获取所有列的值
SELECT Template_ID FROM "Schedule" WHERE "Assignees" IN(6, 3) GROUP BY "Template_ID";
输出:
Template_ID
25
26
我尝试使用以下代码使用Group By来获取表,但它正在获取所有行。
SELECT S1.ID,S1.Template_ID,S1.Assigned_By,S1.Assignees,S1.Active FROM "Schedule" AS S1 INNER JOIN(SELECT Template_ID FROM "Schedule" WHERE "Assignees" IN(6, 3) GROUP BY "Template_ID") AS S2 ON S2.Template_ID=S1.Template_ID
我的输出应该像
ID Template_ID Assigned_By Assignees Active
2 25 1 3 1
6 26 5 6 1
我想知道是否也可以获取列的ID?我使用ID来编辑网络中的记录。
答案 0 :(得分:3)
该查询在MySQL中也无法正常运行,除非偶然。
MySQL中未聚合的列不是SQL标准和not even allowed in MySQL 5.7及更高版本的一部分,除非更改ONLY_FULL_GROUP_BY
模式的默认值。
在早期版本中,结果为is non-deterministic。
服务器可以从每个组中自由选择任何值,因此,除非它们相同,否则选择的值是不确定的。此外,通过添加ORDER BY子句不会影响从每个组中选择值。
这意味着无法知道此查询将返回哪些行:
SELECT S1.ID,S1.Template_ID,S1.Assigned_By,S1.Assignees,S1.Active
FROM "Schedule" AS S1
GROUP BY Template_ID;
要获得确定的结果,您需要一种使用MySQL 8中引入的ranking functions(例如ROW_NUMBER()
)对行进行排名的方法。至少从SQL Server 2012起,它们已经是available in SQL Server。两个数据库的语法都相同:
WITH ranked as AS
(
SELECT
ID,Template_ID,Assigned_By,Assignees Active,
ROW_NUMBER(PARTITION BY Template_ID Order BY ID)
FROM Scheduled
WHERE Assignees IN(6, 3)
)
SELECT ID,Template_ID,Assigned_By,Assignees Active
FROM ranked
Where RN=1
PARTITION BY Template_ID
将结果行根据其Template_ID
值拆分为单独的分区。在该分区内,基于ORDER BY
子句对行进行排序。最后,ROW_NUMBER
为每个有序分区行计算一个行号。