这是previously asked question的后续问题。
我在一个数据库表中有以下数据。
Name LeftId RightId
------------------------------------------
Cat 1
Cat 1
Dog 2
Dog 2
Dog 3
Dog 3
Gerbil 4 5
Cat
Bird
Cow 6
Cow
Cow 7
Dog 8 9
请注意,对于LeftId和RightId,某些行没有数据。
现在,我想做的是找到两个不同的查询
例如
Cat 1
Cow 6 (or 7 .. i'm not worried)
例如
Bird
HMM ..
编辑:正确地重新提出第一个问题。
答案 0 :(得分:2)
对于第一个查询,您需要符合以下两个条件的行:
Name
出现在LeftId
和RightId
都为NULL的同一行的表格中。Name
出现在同一行的表格中,LeftId
和RightId
中至少有一个不为空。嗯,#1由:
完成SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
#2由:
完成SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
你可以相交,看看哪个Name
出现在两个列表中:
SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
INTERSECT
SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
返回:
Name
----
Cat
Cow
但是你想要LeftId
和RightId
,而你不关心哪个,所以我想我们会在名称上聚合:
SELECT Name, MIN(LeftId) AS LeftId, MIN(RightId) AS RightId
FROM Tbl WHERE Tbl.Name IN (
SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
INTERSECT
SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
)
GROUP BY Name
返回
Name LeftId RightId
---- ------ -------
Cat 1
Cow 6 7
lc已建议使用COALESE将这两个ID转换为单个ID。那怎么样:
SELECT Name, COALESCE(MIN(LeftId),MIN(RightId)) AS Id
FROM Tbl WHERE Tbl.Name IN (
SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
INTERSECT
SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
)
GROUP BY Name
返回:
Name Id
---- --
Cat 1
Cow 6
对于第二个查询,您需要符合以下条件的行:
Name
仅出现在没有LeftId
和RightId
我想不出在一组标准中在SQL中进行那种自引用查询的方法,所以我将其分解为两个标准。必须遵守两者才能被接受:
Name
显示在没有LeftId
和RightId
Name
not 会出现在LeftId
或RightId
做#1只是:
SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
但#2很棘手。当然,与#2相反(“Name
或LeftId
行中出现的所有RightId
都与之前相同:
SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
现在是棘手的一点 - 我们希望所有符合#1的行但不遵守#2的相反行。这是 EXCEPT 有用的地方:
SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
EXCEPT
SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
返回:
Name
----
Bird
这就是我们想要的!
答案 1 :(得分:0)
如果我理解正确,那么这是相当微不足道的:
1:
SELECT *
FROM your_table
WHERE (LeftId IS NOT NULL
AND RightId IS NULL)
OR
(LeftId IS NULL
AND RightId IS NOT NULL)
2:
SELECT *
FROM your_table
WHERE
NOT EXISTS
(SELECT * FROM your_table y1
WHERE (y1.LeftId IS NOT NULL OR y1.RightId IS NOT NULL)
AND y1.name = your_table.name)
如果这不对,那么也许你可以澄清一下。
修改:已更新
答案 2 :(得分:0)
查询1)
SELECT *
FROM Table
WHERE (LeftID IS NULL AND RightID IS NOT NULL)
OR (LeftID IS NOT NULL AND RightID IS NULL)
查询2)
SELECT *
FROM Table
WHERE LeftID IS NULL AND RightID IS NULL
答案 3 :(得分:0)
我希望我能在这里正确理解你。
查询1:
SELECT t1.Name, COALESCE(MIN(t1.LeftID), MIN(t1.RightID))
FROM Table t1
WHERE EXISTS(SELECT t2.Name
FROM Table t2
WHERE t2.Name = t1.Name
AND t2.LeftID IS NULL AND t2.RightID IS NULL)
AND COALESCE(MIN(t1.LeftID), MIN(t1.RightID)) IS NOT NULL
GROUP BY t1.Name
查询2:
SELECT t1.Name
FROM Table t1
WHERE NOT EXISTS(SELECT t2.Name
FROM Table t2
WHERE t2.Name = t1.Name
AND (t2.LeftID IS NOT NULL OR t2.RightID IS NOT NULL))
答案 4 :(得分:0)
查询1:
SELECT [Name], [LeftID], [RightID]
FROM [TestTable]
WHERE -- "All rows which have at least 1 Id in one of the two columns"
([LeftID] IS NOT NULL OR [RightID] IS NOT NULL)
OR
-- "Rows with NO data in both of those two Id columns"
([LeftID] IS NULL AND [RightID] IS NULL)
查询2:
SELECT [Name], [LeftID], [RightID]
FROM [TestTable]
WHERE -- "All the rows where LeftId and RightId are NULL
-- grouped by the same name"
([LeftID] IS NULL AND [RightID] IS NULL)
AND
-- "If another row (with the same name) has a value
-- in the LeftId or RightId, this name will not be returned"
([Name] NOT IN (SELECT DISTINCT [Name] FROM [TestTable]
WHERE [LeftID] IS NOT NULL
OR
[RightID] IS NOT NULL))
GROUP BY [Name], [LeftID], [RightID]
结果:
Name LeftID RightID
-------------------------------------------------- ----------- -----------
Cat 1 NULL
Cat 1 NULL
Dog 2 NULL
Dog 2 NULL
Dog NULL 3
Dog NULL 3
Gerbil 4 5
Cat NULL NULL
Bird NULL NULL
Cow 6 NULL
Cow NULL NULL
Cow NULL 7
Dog 8 9
(13 row(s) affected)
Name LeftID RightID
-------------------------------------------------- ----------- -----------
Bird NULL NULL
(1 row(s) affected)