如何清理这些Sql数据?
这是一个问题的后续问题 我在一个db表中有以下数据如何清理这些Sql数据?,sql,sql-server,Sql,Sql Server,这是一个问题的后续问题 我在一个db表中有以下数据 Name LeftId RightId ------------------------------------------ Cat 1 Cat 1 Dog 2 Dog 2 Dog 3 D
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的数据
现在,我想做的是找到两个不同的查询
编辑:正确地改写了第一个问题。如果我理解正确,那么这就相当微不足道了: 1: 2: 如果这不正确,也许你可以澄清一下 编辑:已更新(查询1) 问题2)
我希望我在这里理解正确 问题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
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 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))
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]
问题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
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 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))
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)
对于第一个查询,您需要满足以下两个条件的行:
名称
出现在表中的同一行中,LeftId
和righID
均为空名称
出现在同一行的表中,其中左ID
和右ID
中至少有一个不为空SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
和#2由以下人员完成:
SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
您可以将它们相交以查看两个列表中出现的名称
s:
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
Name Id
---- --
Cat 1
Cow 6
Name
----
Bird
但是您需要LeftId
和righID
,而您不关心哪个,因此我想我们将在名称上聚合:
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
已经建议使用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
----
Cat
Cow
Name Id
---- --
Cat 1
Cow 6
Name
----
Bird
对于第二个查询,您需要符合以下条件的行:
Name
仅在没有LeftId
和righID
Name
出现在没有LeftId
和righID
Name
不会出现在具有LeftId
或righID
的行中SELECT Name FROM Tbl WHERE (LeftId IS NULL) AND (RightId IS NULL)
但是#2很棘手。当然,执行与#2相反的操作(“所有出现在具有LeftId
或righID
的行中的Name
)与前面一样:
SELECT Name FROM Tbl WHERE (LeftId IS NOT NULL) OR (RightId IS NOT NULL)
现在是棘手的一点-我们想要所有服从#1但不服从#2相反的行。这就是除了之外的有用的地方:
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
----
Cat
Cow
Name Id
---- --
Cat 1
Cow 6
Name
----
Bird
这正是我们想要的!第二个是不正确的。对于该查询,我是在所有行(按名称分组)之后,这些行(每个组)都没有Id。因此,在您的代码中,Cow有一行具有两个空值,但它也有一些其他行,其中一个字段具有数字。因此,不应返回Cow。否:(我重新编写了两个q。也许这会有帮助/澄清。第一个查询没有在sql2008中运行。您最好给出您得到的错误。“它没有运行”给我们提供了完全没有依据的信息,我们无法帮助您。但是,我想我可以猜到您需要一个GROUP by子句,因为聚合函数MIN()这就是您得到的错误。我编辑了答案,请重试。