【问题标题】:T-SQL - Find distinct values in table only if joined rows satisfy a list of criteriasT-SQL - 仅当连接行满足条件列表时才在表中查找不同的值
【发布时间】:2015-02-02 00:49:27
【问题描述】:

这对我来说是满口的。 我面临的挑战之一是我不知道如何提出问题 - 这从标题中显而易见。

我将尝试说明我的问题:

我有一张桌子,A:

ID    LocationID
11    185
12    185
13    206

还有一张桌子 B:

ID    AID    Position    Value
1     11     1           4
2     11     3           8
3     11     5           4
4     12     1           4
5     12     2           4
6     12     3           5

表 B 通过 IDAID 关联到表 A。我想构建一个具有以下过滤器的查询: Position = 1 AND Value = 4Position = 3 AND Value = 5 并为我提供了来自 A.ID 的不同 ID 的列表,这些 ID 稳定了所有给定的标准。

我的意思是,如果我通过 INNER JOIN 将两个表连接在一起,我只希望拥有A.ID = 12

我自己解决这个问题的开始是这样的:

SELECT DISTINCT A.ID
FROM A
    INNER JOIN B ON (A.ID = B.AID)
WHERE
    A.LocationID = 185 AND
    (B.Position = 1 AND B.Value = 4) OR
    (B.Position = 3 AND B.Value = 5)

这显然行不通。我以为我有一个明确的解决方案,但当我想到它时,我真的没有。

我有点被这个问题难住了,我很难寻找解决这个问题的策略,因为我什至不知道在我的搜索中使用什么关键字。

【问题讨论】:

    标签: sql sql-server join set-theory


    【解决方案1】:

    您可以使用GROUP BYHAVING 做到这一点:

    SELECT A.ID
    FROM A
        INNER JOIN B ON (A.ID = B.AID)
    GROUP BY A.ID
    HAVING MAX(CASE WHEN A.LocationID = 185 THEN 1 END) = 1
       AND MAX(CASE WHEN B.Position = 1 AND B.Value = 4 THEN 1 END) = 1 
       AND MAX(CASE WHEN B.Position = 3 AND B.Value = 5 THEN 1 END) = 1
    

    演示:SQL Fiddle

    其实可以把@​​987654325@条件移到WHERE

    SELECT A.ID
    FROM Table1 A
        INNER JOIN Table2 B ON (A.ID = B.AID)
    WHERE A.LocationID = 185
    GROUP BY A.ID
    HAVING MAX(CASE WHEN B.Position = 1 AND B.Value = 4 THEN 1 END) = 1 
       AND MAX(CASE WHEN B.Position = 3 AND B.Value = 5 THEN 1 END) = 1
    

    【讨论】:

      【解决方案2】:
      SELECT DISTINCT A.ID
      FROM A
      WHERE A.ID IN(
          SELECT ID 
      FROM B
      WHERE    (B.Position = 1 AND B.Value = 4) OR
          (B.Position = 3 AND B.Value = 5)
      
      )
      

      如果我理解正确的话。

      选择不同的 A.ID 从一个 INNER JOIN B ON (A.ID = B.AID) 在哪里 A.LocationID = 185 和 (B.Position = 1 AND B.Value = 4) 或 (B.Position = 3 AND B.Value = 5)

      【讨论】:

        【解决方案3】:

        您错过了添加括号。

        这就是你的执行方式。

        (A.LocationID = 185
               AND  ( B.Position = 1
                       AND B.Value = 4 ) )
                      OR ( B.Position = 3
                           AND B.Value = 5 )  
        

        AND 的优先级高于OR。试试这个

        SELECT DISTINCT A.ID
        FROM   A
               INNER JOIN B
                       ON ( A.ID = B.AID )
        WHERE  A.LocationID = 185
               AND ( ( B.Position = 1
                       AND B.Value = 4 )
                      OR ( B.Position = 3
                           AND B.Value = 5 ) ) 
        

        【讨论】:

          猜你喜欢
          • 2018-09-24
          • 1970-01-01
          • 1970-01-01
          • 2021-12-07
          • 2022-07-19
          • 1970-01-01
          • 2016-04-11
          • 1970-01-01
          • 2020-01-10
          相关资源
          最近更新 更多