如何在sql表中查找缺失的元素
Posted
技术标签:
【中文标题】如何在sql表中查找缺失的元素【英文标题】:How to find a missing element in a sql table 【发布时间】:2022-01-05 16:25:09 【问题描述】:我有一个 SQL 数据库,其中包含一些由第三人每天添加的数据,每个人必须通过一个表单将 10 行数据添加到我的一个表中,但有时有人忘记添加其中一行,每个行代表不同的结果,我想做的是显示在特定日期和班次中没有插入的行,这是表格的示例
data_id | user | date | shift | machine |
---|---|---|---|---|
3227 | 100 | 28/11/2021 | 1 | TG01 |
3228 | 103 | 28/11/2021 | 1 | TG02 |
3229 | 103 | 28/11/2021 | 1 | TG03 |
3230 | 100 | 28/11/2021 | 1 | TG04 |
3231 | 105 | 28/11/2021 | 1 | TG05 |
3232 | 100 | 28/11/2021 | 1 | TG06 |
3233 | 107 | 28/11/2021 | 1 | TG07 |
3234 | 100 | 28/11/2021 | 1 | TG08 |
3235 | 108 | 28/11/2021 | 1 | TG09 |
3236 | 100 | 28/11/2021 | 1 | TG010 |
3237 | 101 | 28/11/2021 | 2 | TG01 |
3238 | 101 | 28/11/2021 | 2 | TG04 |
3239 | 101 | 28/11/2021 | 2 | TG05 |
3240 | 109 | 28/11/2021 | 2 | TG06 |
3241 | 106 | 28/11/2021 | 2 | TG07 |
3242 | 101 | 28/11/2021 | 2 | TG08 |
每个班次我都必须有 TG01、TG02、TG03 ....TG10,我如何在像班次 2 这样的情况下显示缺少哪些? 我想使用 sql 查询在 powerbi 中显示它,而不必每天手动检查它
【问题讨论】:
您想要一个笛卡尔积(用户、日期、班次、机器)减去您的表格。 提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上述#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。 mysql SQL Server - 请更正您的标签。 @Yitzhak Khabinsky 感谢您的提醒 @Dale K 我同时使用这两个标签,因为我使用 mysql 和 sql-server 具有相同的结构和数据,mysql 仅用于离线测试,而 sql-server 是主要的 【参考方案1】:假设您的数据库已正确规范化,因此您将拥有一个Users
表和一个Shift
表。您还将有一个 Machine
表,其中包含机器 TG01
-TG10
。
您还需要一个名为Dates
的日历表,其中包含每一天的一行。您可以即时生成它,但使用合适的表格会更容易
然后您将它们全部交叉连接,并从表中删除匹配的行
SELECT *
FROM Users u
CROSS JOIN Shift s
CROSS JOIN Machine m
JOIN Dates d ON d.Date BETWEEN '20211101' AND CAST(GETDATE() AS date)
WHERE NOT EXISTS (SELECT 1
FROM YourTable sd
WHERE sd.[User] = u.Id
AND sd.Shift = s.Id
AND sd.Machine = m.Id);
【讨论】:
【参考方案2】:为此我要做的是创建一个简单的堆表,其中一列从 TG01 到 TG10,并使用它检查 NULL 进行 LEFT JOIN。
表格如下所示:
CREATE TABLE HeapTableWithMachines
(
[machine] CHAR(4)
)
然后为机器做 10 次插入。
INSERT INTO HeapTableWithMachines VALUES ('TG01')
INSERT INTO HeapTableWithMachines VALUES ('TG02')
INSERT INTO HeapTableWithMachines VALUES ('TG03')
INSERT INTO HeapTableWithMachines VALUES ('TG04')
INSERT INTO HeapTableWithMachines VALUES ('TG05')
INSERT INTO HeapTableWithMachines VALUES ('TG06')
INSERT INTO HeapTableWithMachines VALUES ('TG07')
INSERT INTO HeapTableWithMachines VALUES ('TG08')
INSERT INTO HeapTableWithMachines VALUES ('TG09')
INSERT INTO HeapTableWithMachines VALUES ('TG10')
然后使用子选择检查已插入但缺少一些机器的班次,方法是执行笛卡尔乘积(即 CROSS JOIN),然后检查整个表。
SELECT
S.[user]
,S.[date]
,S.[shift]
,S.[machine]
FROM (SELECT M.[machine], T0.[user], T0.[date], T0.[shift]
FROM [HeapTableWithMachines] M, [TableWithLinesInsertedByThirdPerson] T0 GROUP BY M.[machine], T0.[user], T0.[date], T0.[shift]) S
LEFT JOIN [TableWithLinesInsertedByThirdPerson] T1 ON S.[date] = T1.[date] AND S.[machine] = T1.[machine] AND S.[shift] = T1.[shift] AND S.[user] = T1.[user] WHERE T1.[user] IS NULL
PS:我同意 Yitzhak Khabinsky 的观点,应该有更多信息可以解决您的问题。
【讨论】:
非常感谢,我仍在努力,因为我想以一种我难以学习的方式来做,你创建堆表的技巧真的给了我一个方向以上是关于如何在sql表中查找缺失的元素的主要内容,如果未能解决你的问题,请参考以下文章