SQL-使用同一个表进行左连接,使用ON语句匹配左表和右表时出现问题

SQL-使用同一个表进行左连接,使用ON语句匹配左表和右表时出现问题,sql,postgresql,Sql,Postgresql,我是SQL新手。考虑下表(表1)< /P> 请只考虑现在的SID ID 2和3。我想要s_id=2的记录,这在s_id=3(v_id 3和5)中不可用。不用担心s_id=3(v_id 8)中的新id 我需要的输出 s_id v_id 2 3 2 5 我尝试了以下查询,但返回的结果与我需要的相反 SELECT a.* from table1 a LEFT JOIN table1 b ON a.v_id = b.v_id WHERE a

我是SQL新手。考虑下表(表1)< /P> 请只考虑现在的SID ID 2和3。我想要s_id=2的记录,这在s_id=3(v_id 3和5)中不可用。不用担心s_id=3(v_id 8)中的新id

我需要的输出

s_id    v_id
2       3
2       5
我尝试了以下查询,但返回的结果与我需要的相反

SELECT a.* 
  from table1 a 
  LEFT 
  JOIN table1 b 
    ON a.v_id = b.v_id 
 WHERE a.s_id = 2 
   AND b.s_id = 3
在这里,我知道ON语句中的条件是错误的。 应该是这样的

a.v_id is not in b.v_id 
这里我不想有一个子查询。 欢迎加入或简单查询。

或者,您可以将您的
JOIN
查询转换为:

或者,您可以将您的
JOIN
查询转换为:


一种有趣的替代方法是使用聚合:

select max(s_id) as s_id, v_id
from t
where s_id in (2, 3)
group by v_id
having not bool_or(s_id = 3)
或相当于:

having bool_and(s_id = 3)

是一种数据库小提琴。

一种有趣的替代方法使用聚合:

select max(s_id) as s_id, v_id
from t
where s_id in (2, 3)
group by v_id
having not bool_or(s_id = 3)
或相当于:

having bool_and(s_id = 3)

是一个db fiddle。

如果您要寻找的解决方案总是比较2和3,或3和4,或5和6(或第一个数字及其上方的数字),那么您可能会在第二个表的b.s_id-1上使用一个左连接到自身,并且只有在第二个表的b.s_id值为空时才使用

您在这里寻找的部分(如果您想避免子查询)也在v_id上加入,然后过滤到b.v_id为NULL的位置

如果您只关心a.s_id=2,请在WHERE子句中指定。使用联接使数据正确地结合在一起

`SELECT a.* 
  from table1 a 
  LEFT 
  JOIN table1 b 
    ON a.s_id = b.s_id -1
   AND a.v_id = b.v_id
 WHERE b.v_id IS NULL
   AND a.s_id = 2`

如果您正在寻找的解决方案总是比较2和3,或3和4,或5和6(或第一个数字和上面的数字),那么对于第二个表,您可能会在b.s_id-1上使用一个左连接到它自己,并且只有在b.s_id的值上第二个连接为空时

您在这里寻找的部分(如果您想避免子查询)也在v_id上加入,然后过滤到b.v_id为NULL的位置

如果您只关心a.s_id=2,请在WHERE子句中指定。使用联接使数据正确地结合在一起

`SELECT a.* 
  from table1 a 
  LEFT 
  JOIN table1 b 
    ON a.s_id = b.s_id -1
   AND a.v_id = b.v_id
 WHERE b.v_id IS NULL
   AND a.s_id = 2`

另一个聚合查询,可能不太可能破坏任何大脑:

SELECT max(s_id) AS s_id, v_id
FROM   tbl
WHERE  s_id in (2, 3)
GROUP  BY v_id
HAVING max(s_id) = 2;
小提琴

(同样,重复
max(suid)
应该会便宜一些。)


列出找到
s_id=2
的所有
v_id
(1次或多次),但不列出更大的
s_id=3
,另一个聚合查询,可能不太可能破坏任何大脑:

SELECT max(s_id) AS s_id, v_id
FROM   tbl
WHERE  s_id in (2, 3)
GROUP  BY v_id
HAVING max(s_id) = 2;
小提琴

(同样,重复
max(suid)
应该会便宜一些。)


列出所有找到
s\u id=2
v\u id
(1次或多次),但不包括更大的
s\u id=3

您使用的是MySQL还是Postgresql?使用的是MySQL还是Postgresql?使用的是Postgresql:-)如果我在任何项目中遇到这种代码,都会伤我的脑筋:-)所以需要另一个评级系统来评估“喜欢”而不是“向上投票”:-:-)如果我在任何项目中遇到此代码,我的大脑都会崩溃:-)因此需要另一个评级系统来“喜欢”而不是“向上投票”:-)