SQL不存在,子查询不存在
我有两张桌子: 个人id、姓名、地址、年龄 知道人物身份,人物身份 我想返回比他们认识的人年长5年以上的人的名字 我正在尝试:SQL不存在,子查询不存在,sql,Sql,我有两张桌子: 个人id、姓名、地址、年龄 知道人物身份,人物身份 我想返回比他们认识的人年长5年以上的人的名字 我正在尝试: SELECT P1.name FROM Persons P1, Persons P2, Knows K1 WHERE P1.id = K1.personA_id AND P2.id = K1.personB_id AND NOT EXISTS (SELECT * FROM Perso
SELECT
P1.name
FROM
Persons P1, Persons P2, Knows K1
WHERE
P1.id = K1.personA_id
AND P2.id = K1.personB_id
AND NOT EXISTS (SELECT *
FROM Persons P3, Persons P4, Knows K2
WHERE P3.id = K2.personA_id
AND P4.id = K2.personB_id
AND (P3.age - P4.age) <= 5)
但它不起作用,我也不知道为什么。你能给我指一下正确的方向吗?提前感谢每个人,找出他们的年龄和他们认识的每个人的年龄。然后计算他们认识的人的最大年龄并过滤掉:
SELECT P1.name
FROM Persons P1 JOIN
Knows K1
ON P1.id = K1.personA_id JOIN
Persons P2
ON P2.id = K1.personB_id
GROUP BY P1.name, P1.age
HAVING ( p1.age - MAX(p2.age) ) > 5;
虽然您可以使用exists来实现这一点,但我认为聚合是一种更简单的查询和逻辑。如果您只需要显示年龄差异大于5岁的关系
SELECT P1.name
FROM Persons P1
INNER JOIN Knows K1 ON P1.id = K1.personA_id
INNER JOIN Persons P2 ON P2.id = K1.personB_id
WHERE (P1.age - P2.age) > 5
如果你只需要让人们知道他们所有的关系都有至少5年的年龄差异,那么@Gordon Linoff答案就是你要找的如果你真的坚持存在的话,这可以做到:
SELECT p1.name AS the_older
, p2.name AS the_younger
FROM Persons p1, Persons p2
WHERE p1.age - p2.age > 5 -- They are more than 5 years older
AND EXISTS ( -- than the one they know
SELECT *
FROM Knows Kx
WHERE Kx.personA_id = p1.id AND Kx.personB_id = p2.id
);
可以使用连接语法执行类似操作。年龄条件也可以移动到连接条件中:
SELECT p1.name AS the_older
, p2.name AS the_younger
FROM Persons p1
JOIN Persons p2 ON EXISTS (
SELECT * FROM Knows Kx
WHERE Kx.personA_id = p1.id AND Kx.personB_id = p2.id
)
WHERE p1.age - p2.age > 5
;
更新:问题澄清后:
人物角色必须有一些朋友
他们都比我小5岁以上
起点是表的并集:
SELECT personA_id ,
personB_id
FROM @k k
UNION
SELECT personB_id ,
personA_id
FROM @k k
因为如果只从表的一侧进行验证,将得到不正确的结果
DECLARE @p TABLE
(
id INT ,
name NVARCHAR(MAX) ,
age INT
)
DECLARE @k TABLE
(
personA_id INT ,
personB_id INT
)
INSERT INTO @p
VALUES ( 1, 'a', 10 ),
( 2, 'b', 14 ),
( 3, 'c', 30 ),
( 6, 'f', 35 ),
( 7, 'g', 45 )
INSERT INTO @k
VALUES ( 1, 2 ),
( 1, 3 ),
( 2, 3 ),
( 7, 6 )
SELECT t.personA_id ,
t.name
FROM ( SELECT personA_id ,
name ,
paage - pbage AS diff
FROM ( SELECT personA_id ,
personB_id ,
pa.age paage ,
pb.age pbage ,
pa.name
FROM @k k
JOIN @p pa ON pa.id = k.personA_id
JOIN @p pb ON pb.id = k.personB_id
UNION
SELECT personB_id ,
personA_id ,
pb.age pbage ,
pa.age paage ,
pb.name
FROM @k k
JOIN @p pa ON pa.id = k.personA_id
JOIN @p pb ON pb.id = k.personB_id
) k
) t
GROUP BY t.personA_id ,
t.name
HAVING ( MIN(diff) > 5 )
输出:
personA_id name
3 c
7 g
personA_id name
7 g
如果您将直接在table Knows上加入,则您将获得:
SELECT t.personA_id ,
t.name
FROM ( SELECT personA_id ,
name ,
paage - pbage AS diff
FROM ( SELECT personA_id ,
personB_id ,
pa.age paage ,
pb.age pbage ,
pa.name
FROM @k k
JOIN @p pa ON pa.id = k.personA_id
JOIN @p pb ON pb.id = k.personB_id
) k
) t
GROUP BY t.personA_id ,
t.name
HAVING ( MIN(diff) > 5 )
输出:
personA_id name
3 c
7 g
personA_id name
7 g
它怎么不起作用?你在用什么RDBMS?那为什么你的意思是它不工作了?我的意思是它没有返回应该返回的东西。对于我想要返回的内容,查询看起来是否正确?它返回了什么?您希望它返回什么?帮我们,帮你,对不起。它什么也不返回。当我在表中看到至少有2个结果时,我确实使用了JOIN来处理另一个查询,但我也无法使用它来处理EXISTS,但恐怕我必须使用notexists来处理这个查询。有什么帮助吗?我是说。你知道为什么我的查询是错误的吗?@GeeKat88为什么你“需要”使用“不存在”?即使我有点理解你的查询,我仍然不完全理解为什么我的查询不起作用。请看项目符号列表。我认为您最初的查询漏掉了第一个项目符号。p1.age-p2.age可能是-10,这将是正确的结果!但是这个查询将排除它;您可以重写和p1.age-p2.age=p1.age-5;它不应该存在。