如何按名称查找不匹配的第 n 个子行?
How to find non-matching nth child rows by name?
我正在尝试编写查询以仅在第 n 个子记录的名称不匹配的情况下查找第 n 个子记录。
简化数据结构:
- Root (PK: id)
- Job (PK: id, FK: idRoot -> Root.id)
- Task (PK: id, FK: idParent -> Job.id, FK: idRoot -> Root.id)
All ID fields are strings (I'm at the mercy of the current design, it's not ours to change)
这个想法是子查询每个根只会获得一个匹配项,并且这些匹配项将针对其他根中的另一个单个匹配项进行评估。除非子查询的所有结果都匹配(在指定的行上),否则它们都会失败。基本上我需要所有第 n 个任务在所有选定的根中都具有相同的名称,否则它们都会失败。
我有一个查询,它为我提供每个根的第 n 个子记录(其中任务是子 table)。但是我不知道如何检查是否相等。此外,这需要同时适用于 SQL Compact 和 SQL Server,这限制了某些功能。
这是 n = 1(第一个任务)
SELECT COUNT(r.id) as RowIndex, t.id, t.idRoot, t.Name
FROM Task t
INNER JOIN Job j ON j.id = t.idParent
INNER JOIN (
SELECT b.id, b.idParent, b.idRoot, b.StartDate
FROM Task b
INNER JOIN Job c ON b.idParent = c.idRec
) r ON t.StartDate >= r.StartDate
AND r.idParent = j.id
AND t.idRoot = r.idRoot
WHERE t.idRoot IN ('1', '2', '3', '4')
AND j.Type LIKE '%Example%'
GROUP BY t.idRoot, t.id, t.Name
HAVING COUNT(r.id) = 1
这给了我类似的东西:
╔══════════╦════╦════════╦════════════╗
║ RowIndex ║ ID ║ IDRoot ║ Name ║
╠══════════╬════╬════════╬════════════╣
║ 1 ║ 4 ║ 2 ║ 1st Task ║
║ 1 ║ 7 ║ 3 ║ 1st Task ║
║ 1 ║ 11 ║ 4 ║ First Task ║
╚══════════╩════╩════════╩════════════╝
所以在上面的结果中,我正确地从 'Example' 作业类型中取回了第一个任务。只有当名称不完全匹配时,我无法弄清楚如何获得结果。如果每个名称都是“第一个任务”,则查询应该 return 不返回任何内容。
更新:
Here's a link 到可以创建 tables 和加载示例数据的 pastebin。
查询A returns作业类型A的第一个任务,结果显示任务名称不匹配。因此,我希望这两个任务 ID 都被 returned.
查询Breturns作业类型B的第一个任务,结果显示所有任务名称匹配。因此,我想要 none 这些任务 ID returned。
尝试使用以下查询:
SELECT
r.ID
, j.TYPE
, t.Name
, t.StartDate
INTO #CoreData
FROM root r
INNER JOIN job j
ON j.idRoot = r.id
INNER JOIN task t
ON t.idParent = j.id
AND t.idRoot = r.id
SELECT
c.ID
, c.Name
, c.StartDate
, c.TYPE
, x.RowID
INTO #CoreDataWithRowID
FROM #CoreData c
CROSS APPLY (
SELECT
COUNT(*) AS RowID
FROM #CoreData cd
WHERE cd.TYPE = c.TYPE
AND cd.ID = c.ID
AND cd.StartDate <= c.StartDate
) x
SELECT
oa.*
FROM #CoreDataWithRowID oa
INNER JOIN #CoreDataWithRowID ob
ON oa.TYPE = ob.TYPE
AND oa.RowID = ob.RowID
AND oa.ID <= ob.ID
WHERE oa.Name != ob.Name
UNION
SELECT
oa.*
FROM #CoreDataWithRowID oa
INNER JOIN #CoreDataWithRowID ob
ON oa.TYPE = ob.TYPE
AND oa.RowID = ob.RowID
AND oa.ID >= ob.ID
WHERE oa.Name != ob.Name
这有望解决 SQL Server Compact Edition 造成的一些限制。
我正在尝试编写查询以仅在第 n 个子记录的名称不匹配的情况下查找第 n 个子记录。
简化数据结构:
- Root (PK: id)
- Job (PK: id, FK: idRoot -> Root.id)
- Task (PK: id, FK: idParent -> Job.id, FK: idRoot -> Root.id)
All ID fields are strings (I'm at the mercy of the current design, it's not ours to change)
这个想法是子查询每个根只会获得一个匹配项,并且这些匹配项将针对其他根中的另一个单个匹配项进行评估。除非子查询的所有结果都匹配(在指定的行上),否则它们都会失败。基本上我需要所有第 n 个任务在所有选定的根中都具有相同的名称,否则它们都会失败。
我有一个查询,它为我提供每个根的第 n 个子记录(其中任务是子 table)。但是我不知道如何检查是否相等。此外,这需要同时适用于 SQL Compact 和 SQL Server,这限制了某些功能。
这是 n = 1(第一个任务)
SELECT COUNT(r.id) as RowIndex, t.id, t.idRoot, t.Name
FROM Task t
INNER JOIN Job j ON j.id = t.idParent
INNER JOIN (
SELECT b.id, b.idParent, b.idRoot, b.StartDate
FROM Task b
INNER JOIN Job c ON b.idParent = c.idRec
) r ON t.StartDate >= r.StartDate
AND r.idParent = j.id
AND t.idRoot = r.idRoot
WHERE t.idRoot IN ('1', '2', '3', '4')
AND j.Type LIKE '%Example%'
GROUP BY t.idRoot, t.id, t.Name
HAVING COUNT(r.id) = 1
这给了我类似的东西:
╔══════════╦════╦════════╦════════════╗
║ RowIndex ║ ID ║ IDRoot ║ Name ║
╠══════════╬════╬════════╬════════════╣
║ 1 ║ 4 ║ 2 ║ 1st Task ║
║ 1 ║ 7 ║ 3 ║ 1st Task ║
║ 1 ║ 11 ║ 4 ║ First Task ║
╚══════════╩════╩════════╩════════════╝
所以在上面的结果中,我正确地从 'Example' 作业类型中取回了第一个任务。只有当名称不完全匹配时,我无法弄清楚如何获得结果。如果每个名称都是“第一个任务”,则查询应该 return 不返回任何内容。
更新:
Here's a link 到可以创建 tables 和加载示例数据的 pastebin。
查询A returns作业类型A的第一个任务,结果显示任务名称不匹配。因此,我希望这两个任务 ID 都被 returned.
查询Breturns作业类型B的第一个任务,结果显示所有任务名称匹配。因此,我想要 none 这些任务 ID returned。
尝试使用以下查询:
SELECT
r.ID
, j.TYPE
, t.Name
, t.StartDate
INTO #CoreData
FROM root r
INNER JOIN job j
ON j.idRoot = r.id
INNER JOIN task t
ON t.idParent = j.id
AND t.idRoot = r.id
SELECT
c.ID
, c.Name
, c.StartDate
, c.TYPE
, x.RowID
INTO #CoreDataWithRowID
FROM #CoreData c
CROSS APPLY (
SELECT
COUNT(*) AS RowID
FROM #CoreData cd
WHERE cd.TYPE = c.TYPE
AND cd.ID = c.ID
AND cd.StartDate <= c.StartDate
) x
SELECT
oa.*
FROM #CoreDataWithRowID oa
INNER JOIN #CoreDataWithRowID ob
ON oa.TYPE = ob.TYPE
AND oa.RowID = ob.RowID
AND oa.ID <= ob.ID
WHERE oa.Name != ob.Name
UNION
SELECT
oa.*
FROM #CoreDataWithRowID oa
INNER JOIN #CoreDataWithRowID ob
ON oa.TYPE = ob.TYPE
AND oa.RowID = ob.RowID
AND oa.ID >= ob.ID
WHERE oa.Name != ob.Name
这有望解决 SQL Server Compact Edition 造成的一些限制。