【问题标题】:Return records in SQL that include all values from IN clause返回包含来自 IN 子句的所有值的 SQL 记录
【发布时间】:2015-09-29 06:17:45
【问题描述】:

抱歉,如果标题不完全准确,但我不确定如何准确表达我的问题。我只想返回结果包括 IN 语句中按特定列分组的所有项目的行。所以我的查询是:

    SELECT [DRSY],
           [DRRT],
           [DRKY],
           [DRDL01]
      FROM dbo.f0005
     WHERE DRKY IN ('FC', 'OO', 'SH')

我想返回 DRSY 和 DRRT 包含所有项目 'FC'、'OO'、'SH' 的记录。也许一张图片可以帮助说明这一点:

我想要返回的唯一行是 DRSY = '00' 和 DRRT = 'DT' 因为这包括我指定的所有 3 个值。我尝试寻找不同的方式来使用 IN、EXISTS 甚至 ALL。

【问题讨论】:

  • 你不能在 WHERE 子句中指定它们吗? WHERE DRSY = '00' 和 DRRT = 'DT'
  • 您使用的是哪个 DBMS?
  • 顺序重要吗,第一个值总是DRSY 和第二个DRRT 等等?
  • 这只是一个例子。我希望能够确定在 where 子句中具有所有值的列 DRSY 和 DRRT 值的所有分组。也可能有 DRSY = '01' 和 DRRT = 'ST' 的组合,它们也具有所有 3 个值。这就是我想要找到的。
  • 抱歉,SQL Server 2012。

标签: sql sql-server tsql exists


【解决方案1】:

您也可以使用intersect 进行操作

SELECT [DRSY], [DRRT] FROM dbo.f0005 WHERE DRKY = 'FC'
INTERSECT
SELECT [DRSY], [DRRT] FROM dbo.f0005 WHERE DRKY = 'OO'
INTERSECT
SELECT [DRSY], [DRRT] FROM dbo.f0005 WHERE DRKY = 'SH' 

【讨论】:

    【解决方案2】:

    我以@StuartLC 的例子做了一些改动。这样我也可以包含表中的其他列。再次感谢斯图尔特!

        WITH drky_count
        AS (SELECT DR.DRSY,
                   DR.DRRT,
                   DR.DRKY,
                   DR.DRDL01,
                   COUNT (DR.DRKY) OVER (PARTITION BY DR.DRSY, DR.DRRT)
                      AS DRKY_COUNT
              FROM f0005 DR
             WHERE DR.DRKY IN ('FC', 'OO', 'SH'))
        SELECT  DRSY, DRRT, DRKY, DRDL01
          FROM drky_count
         WHERE DRKY_COUNT = (SELECT MAX (DRKY_COUNT) FROM drky_count)
    

    【讨论】:

      【解决方案3】:

      我相信这可以通过 GROUPING 然后确保 DISTINCT 计数等于搜索项的数量来完成:

         SELECT [DRSY],
                [DRRT]
         FROM dbo.f0005
         WHERE DRKY IN ('FC', 'OO', 'SH')
         GROUP BY [DRSY], [DRRT]
         HAVING COUNT(DISTINCT DRKY) = 3;
      

      编辑,重新确保项目计数保持同步

      您可以做的是建立一个包含所需值列表的派生表或 CTE (searchValues),然后您可以加入(而不是 IN),然后您将能够COUNT searchValues 避免任何与计数值相关的维护问题。

      WITH searchValues AS
      (
          select val 
          from (values ('FC'), ('OO'), ('SH')) as s(val)
      )
      SELECT [DRSY],
             [DRRT]
         FROM dbo.f0005
         INNER JOIN searchValues s
         ON DRKY = s.val
         GROUP BY [DRSY], [DRRT]
         HAVING COUNT(DISTINCT DRKY) = (SELECT COUNT(val) FROM searchValues);
      

      SqlFiddle here

      【讨论】:

      • 这很好——如果我向 IN 子句添加另一个值,我只需要增加 having 子句中的数字。谢谢!
      • @AndrewCorson 实际上,您可以做的是建立一个包含“搜索”值的表、cte 或派生表,这样可以提高查询的可维护性 - 我已经更新了。
      【解决方案4】:

      怎么样

      SELECT DRSY, DRRT, DRKY, DRDL01 FROM dbo.f0005 a
      WHERE exists (
         SELECT * FROM dbo.f005 b WHERE DRKY = "FC" and a.DRSY = b.DRSY and a.DRRT = b.DRRT
      )
      AND exists (
         SELECT * FROM dbo.f005 c WHERE DRKY = "00" and a.DRSY = c.DRSY and a.DRRT = c.DRRT
      )
      AND exists (
         SELECT * FROM dbo.f005 d WHERE DRKY = "SH" and a.DRSY = d.DRSY and a.DRRT = d.DRRT
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-03
        • 2013-04-08
        • 1970-01-01
        • 2016-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多