Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 与连接逻辑混淆_Sql - Fatal编程技术网

Sql 与连接逻辑混淆

Sql 与连接逻辑混淆,sql,Sql,我发现它如此混乱,以至于我的简单逻辑不起作用 我有一个包含两列ID和代码的数据 1个ID可以链接到多个代码 因此,样本数据如下所示: ID Code -- ---- a 1 a 2 a 3 b 1 b 3 c 1 c 3 c 4 d 2 d 3 d 4 规则是: 查找代码为1且代码不等于2且代码为3的ID 很明显,a是失败的,b是好的,c是好的,d是失败的 我有下面两种方法,它们都不起作用 你能帮忙吗 非常感谢, 哈利

我发现它如此混乱,以至于我的简单逻辑不起作用

我有一个包含两列ID和代码的数据

1个ID可以链接到多个代码

因此,样本数据如下所示:

ID   Code
--   ----
a    1
a    2
a    3
b    1
b    3
c    1
c    3
c    4
d    2
d    3
d    4
规则是:

查找代码为1且代码不等于2且代码为3的ID 很明显,a是失败的,b是好的,c是好的,d是失败的

我有下面两种方法,它们都不起作用

你能帮忙吗

非常感谢,

哈利

方法1:

create table mytable (
ID int,
code varchar(255)
);

insert into mytable (ID, code)
values('a','1'),('a','2'),('a','3'),('b','1'),('b','3'),('c','1'),('c','3'),('c','4'),('d','2'),('d','3'),('d','4');


select distinct 
    ID 
from 
    mytable 
where 
    code = 1
    and ID not in (select ID from mytable where code = 2)
    and ID in (select ID from mytable where code = 3);
方法2:加入我的表2次

select distinct(T1.ID) 
from
    (select distinct(mytable1.ID) 
     from mytable mytable1 
     join mytable mytable2 on  mytable1.ID = mytable2.ID
     where mytable1.code = 1 
       and mytable2.code not in ('2')) as T1
join
    (select distinct(mytable3.ID) 
     from mytable mytable3 
     where mytable3.code = 3) as T2 
on T1.ID = T2.ID

我会在这里使用聚合:

SELECT ID
FROM (SELECT DISTINCT ID, code FROM mytable) t
GROUP BY ID
HAVING
    COUNT(CASE WHEN code = 1 THEN 1 END) > 0 AND
    COUNT(CASE WHEN code = 2 THEN 1 END) +
        COUNT(CASE WHEN code = 3 THEN 1 END) < 2;

HAVING子句确保任何匹配ID的代码为1,并且代码为2或3的情况最多只发生一次,即禁止同时使用代码2和代码3,尽管允许使用其中一个或另一个。

欢迎使用S/O。随着时间的推移,阅读其他人和其他反馈,您的帖子会变得更好。您的问题说明了一件事,但查询提供了另一件事

单独部分上的WHERE子句要求代码=1,相应的ID没有代码=2,但除了代码=1外,它还有代码=3

where 
    code = 1
    and ID not in (select ID from mytable where code = 2)
    and ID in (select ID from mytable where code = 3);
除了聚合之外,您还可以根据需要使用相同的表和自联接。在本例中,我可以从您的基本查询开始,只查询code=1。然后我会在同一个ID上再次加入,但它也有一个代码3,需要1和3。然后是代码2的第三个左连接,并确保未找到它

select
      t1.id
   from
      MyTable t1
         -- now, does it also exist for the same "ID" but also have code = 3
         JOIN MyTable t2
            on t1.id = t2.id
            AND t2.code = 3
         -- here, I am explicitly LOOKING for code = 2 for same ID.
         -- but by doing a LEFT-JOIN, I only want where it does NOT exist
         LEFT JOIN MyTable t3
            on t1.id = t3.id 
            AND t3.code = 2
   where
          t1.code = 1
      -- explicitly making sure the is no match for same ID, code = 2
      AND t3.id IS NULL
另一种方法是通过聚合,但得到的计数为1和3,另一种方法是代码=2,但确保计数符合您的需要

select
      t1.id
   from
      MyTable t1
   having
          sum( case when t1.code = 1 then 1 else 0 end ) > 0
      AND sum( case when t1.code = 3 then 1 else 0 end ) > 0
      AND sum( case when t1.code = 2 then 1 else 0 end ) = 0
   group by
      t1.id
在上面的例子中,假设给定ID的多条记录的代码=1,则可能会得到大于1的计数。因此,我只对代码1求和,并且只关心它是否至少有1。对于代码=3且总和至少为1的类似要求。最后,代码之和=2,确保其计数为=0

对OP第二次查询的反馈

在第二次查询中失败的原因在join for code test=3之前的第一部分中

select distinct(T1.ID) 
from
    (select distinct(mytable1.ID) 
     from mytable mytable1 
     join mytable mytable2 on  mytable1.ID = mytable2.ID
     where mytable1.code = 1 
       and mytable2.code not in ('2')) as T1
您正在查询table1.code=1的位置,这是确定的,然后您从table1到table2的连接仅在ID上

id   code
a    1
a    2
a    3

您的自加入正在返回代码为1、2和3的记录。因此,尽管您可能不想要2,但它仍在引入ID 1和3,这两个ID确实符合条件,因此逻辑上是失败的。这就是为什么在我的第一个示例中,我在同一个id上进行左连接,并显式地使用code=2。。。但是where子句被表3别名ID为NULL的地方显式排除,这意味着它看不到相同ID的记录,代码=2。

不能有代码为1和3的行。为什么在我的第二种方法中,ID a是有效的?对于SQL新手来说,有没有更容易消化的方法?但是我不知道为什么我的查询不起作用。我看起来很合乎逻辑。请启发我,因为我的实际工作比这个例子更复杂。感谢你有其他的方法来解决你的问题,但老实说,我认为我的答案是最简单的方法。@ Nick,事实上我的答案检查代码2和3不一起发生。非常感谢你的解释。你能告诉我为什么我的第二种方法会得出错误的答案吗?这让我很生气@Harry,请参阅我答案的修订,以澄清您的收益率不正确的原因。