分组BY语句错误以获取唯一记录

时间:2019-05-30 06:45:44

标签: sql sql-server group-by

我是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来编辑网络中的记录。

1 个答案:

答案 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为每个有序分区行计算一个行号。