繁体   English   中英

SQL XOR语法不起作用

[英]SQL XOR syntax isn't working

我注意到SQL SERVER EXPRESS中没有XOR函数,因此我尝试使用旧方法。

select NCLI
from   CLIENT
where  NCLI in (select NCLI
            from   COMMANDE
       where  NCOM in (select NCOM
            from   DETAIL
            where  ((NPRO = 'PA60' and NPRO <> 'PA45')
           or (NPRO <> 'PA60' and NPRO = 'PA45'))))

现在,我不是数学专家,但据我所知,这应该给我提供仅订购PA60或PA45而不订购两者的客户数量(NCLI)。

结果是,它同时也为同时订购两者的人员提供了NCLI。

我再次检查了我的旧数学课程,但是我不知道我在这里缺少什么。

where条件被施加到单个行的列,而不是一组行。

条件:

可以使用group by子句解决:

select NCOM
from  DETAIL
where NPRO IN ('PA60','PA45')
group by ncom
having count(distinct NPRO) = 1

仅当同一客户可以在同一产品的detail表中出现多次时,才需要使用唯一的distinct NPRO 否则, count(*)也将起作用(但在此对distinct不会造成任何损害)。

上面的内容还将返回仅订购PA60和其他产品的客户。 如果您还想排除那些商品,则需要添加其他条件,以仅包括订购商品数量等于商品数量的商品。

select NCOM
from  DETAIL
where NPRO IN ('PA60','PA45')
group by ncom
having count(NPRO) = 1
   and count(NPRO) = (select count(*) 
                      from  DETAIL d2
                      where d2.ncom = detail.ncom)

第二个条件也可以放在where部分。

这个大的条件表达式只查看同一行中的数据,而不是每一行中的数据。

要执行所需的操作,您需要将表与其自身进行比较(JOIN),以便可以将每一行与其他行进行比较。 您可以使用排除联接来执行此操作,在该联接中您对表进行了左联接以寻找某种条件,然后在where子句中通过将结果限制为NULL记录来限制第二个表中某个字段的记录,从而排除所有匹配项为NULL。

将此应用于您的问题,然后最里面的select查询应如下所示:

select d1.NCOM
from   DETAIL d1
left join DETAIL d2 on d2.NCOM = d1.NCOM and d2.NPRO <> d1.NPRO and d2.NPRO IN ('PA60', 'PA45')
where d1.NPRO IN ('PA60', 'PA45') and d2.NCOM IS NULL

有时您可以通过NOT EXISTS查询而不是排除联接来使它更好地执行,这一点也不值钱,但是我发现排除联接更容易使用。

有了这一点,我们还应该将其他嵌套的select编写为JOIN:

select cl.NCLI
from   DETAIL d1
left join DETAIL d2 on d2.NCOM = d1.NCOM and d2.NPRO <> d1.NPRO and d2.NPRO IN ('PA60', 'PA45')
inner join COMMANDE cm on cm.NCOM = d1.NCOM
inner join CLIENT cl on cl.NCLI = cm.NCLI
where d1.NPRO IN ('PA60', 'PA45') and d2.NCOM IS NULL

根据表中的关系,您可能还需要为此添加一个distinct的内容。

where  NCOM in 
(select NCOM from   DETAIL where  (
(NPRO = 'PA60' and NPRO <> 'PA45')
or (NPRO <> 'PA60' and NPRO = 'PA45')
)

您应该注意到, 为每行都处理WHERE ,这意味着您在子句中进行了多余的检查。

每当NPRO值保存PA60 ,很明显它不会在同一行中保存任何其他值(因为它不是ARRAY )。

相同的规则适用于第二个条件。

WHERE其实看起来像

WHERE NCOM IN ( SELECT NCOM FROM DETAIL WHERE NPRO = 'PA60' OR NPRO = 'PA45' )

所以这个子查询让你NCOM所有NPROIN ('PA60','PA45')

而且每走一步,对于您想要的情况都会产生错误的结果。

有多种写方法,但这可能是您所掌握的最简单的方法。

SELECT NCLI
FROM CLIENT
WHERE NCLI IN (
    SELECT NCLI
    FROM COMMANDE
    WHERE NCOM IN (
        SELECT NCOM
        FROM DETAIL
        WHERE NPRO IN ('PA60', 'PA45')
            AND NCOM NOT IN (
                SELECT NCOM
                FROM DETAIL
                WHERE NPRO = 'PA60'

                INTERSECT

                SELECT NCOM
                FROM DETAIL
                WHERE NPRO = 'PA45'
                )
        )
    )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM