为SQL查询添加一些逻辑

时间:2009-10-22 15:06:41

标签: sql

首先,我在sql上真的不是那么棒,据说这个问题是:

假设我有一张名为Abilities的表。 在此示例中,Abilities具有ID,PersonID,Text。

让我说我做了一个搜索,我指明我想要清楚地列出每个有能力'飞','开车','唱'但没有能力'打'','滑板'的人

无论如何要编写这样的查询,最终只会返回与上述语句匹配的行吗?表和它的内容纯粹是虚构的我可能会添加,因此很奇怪:P

我非常感谢这方面的帮助,因为它是一个相当复杂的数据库搜索工具。

由于

5 个答案:

答案 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'))