sql - 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 来编辑网络中的记录。
解决方案
该查询在 MySQL 中也不能按预期工作,除非是偶然的。
MySQL 中的非聚合列不是 SQL 标准的一部分,甚至在 MySQL 5.7 及更高版本中也不允许,ONLY_FULL_GROUP_BY
除非更改模式的默认值。
在早期版本中,结果是不确定的。
服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,从每个组中选择值不会受到添加 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 中引入的排名函数ROW_NUMBER()
对行进行排名的方法,例如. 至少自 SQL Server 2012 起,这些在 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
计算每个有序分区行的行号。
推荐阅读
- android - 带有改造的无效网络请求
- pandas - 是否可以在 NamedAgg 表达式中使用带空格的列名?
- c# - Azure Cognitve Services [Face API] 使用 SDK 和容器有什么区别
- javascript - 如何为 PHP 格式化 JS 对象数组?
- firebase - 如何在 Firebase 应用分发中禁用分发
- html - 如何在托管网站时在 Hostinger 中的 CSS 中设置背景中任何图像的路径?
- jquery - 在 datetimepicker 中选择一周的最后一天
- sql - 从不同的多列中删除相同的排列
- android - 如何通过 Google Map API 获取公路距离
- html - 从 HTML、CSS 中的模板中删除滑块