首先,我在sql上真的不是那么棒,据说这个问题是:
假设我有一张名为Abilities的表。 在此示例中,Abilities具有ID,PersonID,Text。
让我说我做了一个搜索,我指明我想要清楚地列出每个有能力'飞','开车','唱'但没有能力'打'','滑板'的人
无论如何要编写这样的查询,最终只会返回与上述语句匹配的行吗?表和它的内容纯粹是虚构的我可能会添加,因此很奇怪:P
我非常感谢这方面的帮助,因为它是一个相当复杂的数据库搜索工具。
由于
答案 0 :(得分:5)
SELECT a.PersonId
FROM Abilities a
JOIN Abilities b ON (a.PersonId = b.PersonId AND b.text = 'Drive')
JOIN Abilities c ON (a.PersonId = c.PersonId AND c.text = 'Sing')
LEFT JOIN Abilities d ON (a.PersonId = d.PersonId AND d.text = 'Flight')
LEFT JOIN Abilities e ON (a.PersonId = e.PersonId AND e.text = 'Skateboard')
WHERE a.text = 'Fly' AND d.Id IS NULL and e.Id IS NULL
我看到你有几个答案试图在相同的能力实例上进行IN和NOT IN测试,但这不起作用 - 你显然需要测试不同的能力实例,从而需要这个多重自我-join!
答案 1 :(得分:3)
根据实际数据和查询参数,没有自连接的方法可能更有效。我希望这可以对表进行一次完整的扫描,而join方法可能会进行很多索引查找。
SELECT personID FROM
(
SELECT personID,
SUM(CASE WHEN text IN ('Fly','Drive','Sing') THEN 1 ELSE 0 END) good_stuff,
SUM(CASE WHEN text IN ('Fight','Skateboard') THEN 1 ELSE 0 END) bad_stuff
FROM abilities
GROUP BY personID
)
WHERE good_stuff = 3 and bad_stuff = 0
答案 2 :(得分:1)
有很多方法可以解决这个问题。我选择了一个应该是可读的,但不一定能够进行大量修改。
WITH Fliers AS (
SELECT PersonID
FROM Abilities
WHERE Text = 'Fly'
),
Drivers AS (
SELECT PersonID
FROM Abilities
WHERE Text = 'Drive'
),
Singers AS (
SELECT PersonID
FROM Abilities
WHERE Text = 'Sing'
),
Fighters AS (
SELECT PersonID
FROM Abilities
WHERE Text = 'Fight'
),
Skateboarders AS (
SELECT PersonID
FROM Abilities
WHERE Text = 'Skateboard'
)
SELECT *
FROM People
INNER JOIN Fliers
ON Fliers.PersonID = People.PersonID
INNER JOIN Drivers
ON Drivers.PersonID = People.PersonID
INNER JOIN Singers
ON Singers.PersonID = People.PersonID
LEFT JOIN Fighters
ON Fighters.PersonID = People.PersonID
LEFT JOIN Skateboarders
ON Skateboarders.PersonID = People.PersonID
WHERE Fighters.PersonID IS NULL
AND Skateboarders.PersonID IS NULL
但是有很多方法可以让这只猫受伤。
这里的大多数解决方案都使用简单的IN,而不是IN,但它们不会给出我认为你期望的结果 - 即那些拥有Fly AND Drive AND Sing AND NEITHER Fight NOR Skateboard的人
答案 3 :(得分:1)
SELECT * FROM ( SELECT PERSONID, COUNT(SKILLS) FROM DUMMY WHERE SKILLS IN ('FLY','DRIVE','SING') GROUP BY PERSONID HAVING COUNT(*)=3 ) A
WHERE PERSONID NOT IN
( SELECT DISTINCT PERSONID FROM DUMMY WHERE SKILLS IN ('FIGHT','SKATEBOARD') )
答案 4 :(得分:0)
您没有指定数据库服务器,但我知道这可以在SQL Server中使用
SELECT a1.ID, a1.PersonID, a1.Text
FROM Abilities a1
WHERE a1.Text IN ('Fly', 'Drive', 'Sing')
AND NOT EXISTS (SELECT ID
FROM Abilities a2
WHERE a2.ID = a1.ID
AND a2.Text IN ('Fight', 'Skateboard'))