代码之家  ›  专栏  ›  技术社区  ›  MattE

SQL无法获取WHERE EXISTS子句以正常工作,并且只能返回在特定日期内具有客户端类型的行。

  •  1
  • MattE  · 技术社区  · 6 年前

    好吧,这让我发疯了,我相信解决办法会很简单,我可能会把我的头撞到墙上。我有一个查询,其中有客户数据。在某些查询中,我只希望某个日期之间的客户在该日期范围内的某个时间点进行了客户访问,该日期范围对应于呼叫报告ID的3、8或12。对于这些客户机,我希望它返回日期范围内的所有数据,而不仅仅是包含此客户机访问代码的行。对于其他没有客户访问的客户,我想从数据中排除他们。

    这就是我一直在玩的东西,根本不能让它工作。

    SELECT * 
    FROM CV.Data AS CV 
    WHERE EXISTS (SELECT * 
                  FROM CV.Data AS CVD 
                  WHERE CVD.Call_Report_ID IN(3,8,12) 
                      AND CVD.User_ID = 33) 
        AND CV.User_ID = 33 
        AND CV.Activity_Date BETWEEN '10/1/2018' AND '3/31/2019'
    

    下面是我想要的一个例子:

    Cust_ID Call_Report_ID Activity_Date
      5         3            10/15/2018
      5         7            10/28/2018
      6         9            10/21/2018
      6         11           10/25/2018 
    

    在上面运行此查询时,我希望它返回来自客户5的两行,因为它们在日期范围内的任何一行中都具有3、8或12的调用报告ID,并且从客户6中排除这两行,因为它们在日期范围内没有具有这些类型的调用报告ID。

    但是,每次运行它时,它都会返回此用户的所有行,而不仅仅是在where exists子查询中指定的行。

    我在这出什么事了?

    5 回复  |  直到 6 年前
        1
  •  0
  •   Egan Wolf    6 年前

    您没有以任何方式将子查询与外部查询联接起来。

    SELECT * 
    FROM CV.Data AS CV 
    WHERE EXISTS (SELECT * 
                  FROM CV.Data AS CVD 
                  WHERE CVD.Call_Report_ID IN(3,8,12) 
                      AND CVD.User_ID = 33
                      AND CV.Cust_ID = CVD.Cust_ID) <--
        AND CV.User_ID = 33 
        AND CV.Activity_Date BETWEEN '10/1/2018' AND '3/31/2019'
    
        2
  •  1
  •   Amir Molaei    6 年前

    替代 Exist 具有 in :

    SELECT * 
    FROM Data AS CV 
    WHERE Cust_ID in (SELECT Cust_ID 
                  FROM Data AS CVD 
                  WHERE CVD.Call_Report_ID IN(3,8,12) 
                      AND CVD.User_ID = 33) 
        AND CV.User_ID = 33 
        AND CV.Activity_Date BETWEEN '10/1/2018' AND '3/31/2019'
    
        3
  •  0
  •   forpas    6 年前

    它返回此用户的所有行,而不仅仅是 存在子查询的位置

    这个 EXISTS 不筛选查询返回的数据。
    它返回 TRUE FALSE .
    所以如果它回来了 错误的 将会有 无行 由您的查询返回
    如果它回来了 真的 所有的行 在以下条件下:

    CV.User_ID = 33 AND CV.Activity_Date BETWEEN '10/1/2018' AND '3/31/2019'  
    

    将被退回

        4
  •  0
  •   Mr Zach    6 年前

    它返回所有行,因为您没有在exists查询中进行任何筛选。

    我认为最好更改这个查询,这样您就可以使用join。

        5
  •  0
  •   Bartosz Siemasz    6 年前

    这个怎么样:

    SELECT * 
    FROM CV.Data AS CV 
    WHERE EXISTS (SELECT * 
              FROM CV.Data AS CVD 
              WHERE CVD.Call_Report_ID IN(3,8,12) 
                  AND CVD.User_ID = 33) 
    AND CV.User_ID = 33 
    AND CV.Activity_Date BETWEEN '10/1/2018' AND '3/31/2019'
    AND CV.Call_Report_ID IN(3,8,12)
    

    如果我是你,我会想为什么我需要这个存在的条件,它确实不是直接向前过滤,但是我没有足够的信息从你那里简单地丢弃它。

    你可以把我的回答看作是一个有用的提示,但是想想为什么你需要这个存在的条件。看起来不需要,查询如下:

    SELECT * 
    FROM CV.Data AS CV 
    WHERE CV.User_ID = 33 
    AND CV.Activity_Date BETWEEN '10/1/2018' AND '3/31/2019'
    AND CV.Call_Report_ID IN(3,8,12)