如何在 sql table 中查找缺失的元素
How to find a missing element in a sql table
我有一个 SQL 数据库,其中包含一些每天由第三方添加的数据,每个人都必须通过表格向我的 table 之一添加 10 行数据,但是有时有人忘记添加其中一行,每行代表不同的结果,我想做的是显示在特定日期和班次中未插入的行,这里是 table
的示例
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 中显示它,而不必每天手动检查它
为此我要做的是创建一个简单的堆 table,其中一列从 TG01 到 TG10,然后执行 LEFT JOIN 并检查 NULL。
table 看起来像这样:
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,然后检查整个 table。
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 的观点,应该有更多信息来解决您的问题。
人们会假设您的数据库已正确规范化,因此您将有一个 Users
table,以及一个 Shift
table。您还将有一个 Machine
table 包含机器 TG01
-TG10
.
您还需要一个名为 Dates
的日历 table,包含每一天的一行。您可以即时生成它,但使用适当的 table
会更容易
然后将它们全部交叉连接起来,并从 table
中删除匹配的行
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);
我有一个 SQL 数据库,其中包含一些每天由第三方添加的数据,每个人都必须通过表格向我的 table 之一添加 10 行数据,但是有时有人忘记添加其中一行,每行代表不同的结果,我想做的是显示在特定日期和班次中未插入的行,这里是 table
的示例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 中显示它,而不必每天手动检查它
为此我要做的是创建一个简单的堆 table,其中一列从 TG01 到 TG10,然后执行 LEFT JOIN 并检查 NULL。
table 看起来像这样:
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,然后检查整个 table。
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 的观点,应该有更多信息来解决您的问题。
人们会假设您的数据库已正确规范化,因此您将有一个 Users
table,以及一个 Shift
table。您还将有一个 Machine
table 包含机器 TG01
-TG10
.
您还需要一个名为 Dates
的日历 table,包含每一天的一行。您可以即时生成它,但使用适当的 table
然后将它们全部交叉连接起来,并从 table
中删除匹配的行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);