根据条件在 SQL table 中查找缺失的条目
Find missing entries in a SQL table conditional on criteria
我有一些简单的 SQL 经验(在此处使用 MS SQL 服务器 2012),但这让我望而却步。我希望从 table(之前从连接成功创建)中输出不同的名称,其中缺少一些必需的条目,但条件是存在另一个类似的条目。对于位置 90 的任何人,我想检查他们是否也有位置 10 和 20...
例如,考虑这个 table:
Name |Number |Location
--------|-------|--------
Alice |136218 |90
Alice |136218 |10
Alice |136218 |20
Alice |136218 |40
Bob |121478 |10
Bob |121478 |90
Chris |147835 |20
Chris |147835 |90
Don |138396 |20
Don |138396 |10
Emma |136412 |10
Emma |136412 |20
Emma |136412 |90
Fred |158647 |90
Gay |154221 |90
Gay |154221 |10
Gay |154221 |30
正式来说,我想获得 table who:
中那些条目的名称(和编号)
- 在位置 90 有一个条目
- 并且没有所有其他必需的位置条目 - 在本例中还有 10 和 20。
所以在上面的例子中
- 这个查询没有输出 Alice 和 Emma,他们有 90、10 和 20 的条目(都存在并且正确,我们忽略位置 40 条目)。
- 此查询未输出 Don,他没有位置 90 的条目。
- 此查询输出 Bob 和 Gay,他们都缺少位置 20(我们忽略 Gay 的位置 30 条目)。
- Chris 是此查询的输出,他缺少位置 10。
- 此查询输出 Fred,他缺少位置 10 和 20。
因此,所需的查询输出类似于:
Name |Number |Location
--------|-------|--------
Bob |121478 |20
Chris |147835 |10
Fred |158647 |10
Fred |158647 |20
Gay |154221 |20
我已经尝试了一些方法 left/right join where B.Key is null, and select from ... except 但到目前为止我还不能完全理解逻辑方法正确。在原来的 table 中有数十万个条目,只有几十个有效的缺失匹配项。不幸的是,我不能使用任何计算条目的东西,因为查询必须是特定位置的,并且在所需位置之外的其他位置还有其他有效的 table 条目。
我觉得这样做的正确方法是类似于左外部连接,但是作为起始 table 是另一个连接的输出,这是否需要声明一个中间 table 然后是外部连接加入中间体 table 和它自己?请注意,不需要填写任何空白或在 table.
中输入项目
如有任何建议,我们将不胜感激。
===粘贴在这里的已回答和使用的代码===
--STEP 0: Create a CTE of all valid actual data in the ranges that we want
WITH ValidSplits AS
(
SELECT DISTINCT C.StartNo, S.ChipNo, S.TimingPointId
FROM Splits AS S INNER JOIN Competitors AS C
ON S.ChipNo = C.ChipNo
AND (
S.TimingPointId IN (SELECT TimingPointId FROM @TimingPointCheck)
OR
S.TimingPointId = @TimingPointMasterCheck
)
),
--STEP 1: Create a CTE of the actual data that is specific to the precondition of passing @TimingPointMasterCheck
MasterSplits AS
(
SELECT DISTINCT StartNo, ChipNo, TimingPointId
FROM ValidSplits
WHERE TimingPointId = @TimingPointMasterCheck
)
--STEP 2: Create table of the other data we wish to see, i.e. a representation of the StartNo, ChipNo and TimingPointId of the finishers at the locations in @TimingPointCheck
--The key part here is the CROSS JOIN which makes a copy of every Start/ChipNo for every TimingPointId
SELECT StartNo, ChipNo, Missing.TimingPointId
FROM MasterSplits
CROSS JOIN (SELECT * FROM @TimingPointCheck) AS Missing(TimingPointId)
EXCEPT
SELECT StartNo, ChipNo, TimingPointId FROM ValidSplits
ORDER BY StartNo
欢迎来到 Stack Overflow。
您需要的东西有点挑战性,因为您想查看不存在的数据。
因此,我们首先必须创建所有可能的行,然后减去存在的行
select ppl_with_90.Name,ppl_with_90.Number,search_if_miss.Location
from
(
select distinct Name,Number
from yourtable t
where Location=90
)ppl_with_90 -- All Name/Numbers that have the 90
cross join (values (10),(20)) as search_if_miss(Location) -- For all the previous, combine them with both 10 and 20
except -- remove the lines already existing
select *
from yourtable
where Location in (10,20)
您需要为位置 = 90 的所有行生成 由 name, number, 10_and_20
组成的集合。然后您可以使用您喜欢的方法(左连接 + 空,不exists, not in)过滤不存在的行:
WITH name_number_location AS (
SELECT t.Name, t.Number, v.Location
FROM @yourdata AS t
CROSS JOIN (VALUES (10), (20)) AS v(Location)
WHERE t.Location = 90
)
SELECT *
FROM name_number_location AS r
WHERE NOT EXISTS (
SELECT *
FROM @yourdata AS t
WHERE r.Name = t.Name AND r.Location = t.Location
)
我有一些简单的 SQL 经验(在此处使用 MS SQL 服务器 2012),但这让我望而却步。我希望从 table(之前从连接成功创建)中输出不同的名称,其中缺少一些必需的条目,但条件是存在另一个类似的条目。对于位置 90 的任何人,我想检查他们是否也有位置 10 和 20...
例如,考虑这个 table:
Name |Number |Location
--------|-------|--------
Alice |136218 |90
Alice |136218 |10
Alice |136218 |20
Alice |136218 |40
Bob |121478 |10
Bob |121478 |90
Chris |147835 |20
Chris |147835 |90
Don |138396 |20
Don |138396 |10
Emma |136412 |10
Emma |136412 |20
Emma |136412 |90
Fred |158647 |90
Gay |154221 |90
Gay |154221 |10
Gay |154221 |30
正式来说,我想获得 table who:
中那些条目的名称(和编号)- 在位置 90 有一个条目
- 并且没有所有其他必需的位置条目 - 在本例中还有 10 和 20。
所以在上面的例子中
- 这个查询没有输出 Alice 和 Emma,他们有 90、10 和 20 的条目(都存在并且正确,我们忽略位置 40 条目)。
- 此查询未输出 Don,他没有位置 90 的条目。
- 此查询输出 Bob 和 Gay,他们都缺少位置 20(我们忽略 Gay 的位置 30 条目)。
- Chris 是此查询的输出,他缺少位置 10。
- 此查询输出 Fred,他缺少位置 10 和 20。
因此,所需的查询输出类似于:
Name |Number |Location
--------|-------|--------
Bob |121478 |20
Chris |147835 |10
Fred |158647 |10
Fred |158647 |20
Gay |154221 |20
我已经尝试了一些方法 left/right join where B.Key is null, and select from ... except 但到目前为止我还不能完全理解逻辑方法正确。在原来的 table 中有数十万个条目,只有几十个有效的缺失匹配项。不幸的是,我不能使用任何计算条目的东西,因为查询必须是特定位置的,并且在所需位置之外的其他位置还有其他有效的 table 条目。
我觉得这样做的正确方法是类似于左外部连接,但是作为起始 table 是另一个连接的输出,这是否需要声明一个中间 table 然后是外部连接加入中间体 table 和它自己?请注意,不需要填写任何空白或在 table.
中输入项目如有任何建议,我们将不胜感激。
===粘贴在这里的已回答和使用的代码===
--STEP 0: Create a CTE of all valid actual data in the ranges that we want
WITH ValidSplits AS
(
SELECT DISTINCT C.StartNo, S.ChipNo, S.TimingPointId
FROM Splits AS S INNER JOIN Competitors AS C
ON S.ChipNo = C.ChipNo
AND (
S.TimingPointId IN (SELECT TimingPointId FROM @TimingPointCheck)
OR
S.TimingPointId = @TimingPointMasterCheck
)
),
--STEP 1: Create a CTE of the actual data that is specific to the precondition of passing @TimingPointMasterCheck
MasterSplits AS
(
SELECT DISTINCT StartNo, ChipNo, TimingPointId
FROM ValidSplits
WHERE TimingPointId = @TimingPointMasterCheck
)
--STEP 2: Create table of the other data we wish to see, i.e. a representation of the StartNo, ChipNo and TimingPointId of the finishers at the locations in @TimingPointCheck
--The key part here is the CROSS JOIN which makes a copy of every Start/ChipNo for every TimingPointId
SELECT StartNo, ChipNo, Missing.TimingPointId
FROM MasterSplits
CROSS JOIN (SELECT * FROM @TimingPointCheck) AS Missing(TimingPointId)
EXCEPT
SELECT StartNo, ChipNo, TimingPointId FROM ValidSplits
ORDER BY StartNo
欢迎来到 Stack Overflow。
您需要的东西有点挑战性,因为您想查看不存在的数据。 因此,我们首先必须创建所有可能的行,然后减去存在的行
select ppl_with_90.Name,ppl_with_90.Number,search_if_miss.Location
from
(
select distinct Name,Number
from yourtable t
where Location=90
)ppl_with_90 -- All Name/Numbers that have the 90
cross join (values (10),(20)) as search_if_miss(Location) -- For all the previous, combine them with both 10 and 20
except -- remove the lines already existing
select *
from yourtable
where Location in (10,20)
您需要为位置 = 90 的所有行生成 由 name, number, 10_and_20
组成的集合。然后您可以使用您喜欢的方法(左连接 + 空,不exists, not in)过滤不存在的行:
WITH name_number_location AS (
SELECT t.Name, t.Number, v.Location
FROM @yourdata AS t
CROSS JOIN (VALUES (10), (20)) AS v(Location)
WHERE t.Location = 90
)
SELECT *
FROM name_number_location AS r
WHERE NOT EXISTS (
SELECT *
FROM @yourdata AS t
WHERE r.Name = t.Name AND r.Location = t.Location
)