【问题标题】:Select IDs from multiple rows where column values satisfy one condition but not another从列值满足一个条件但不满足另一个条件的多行中选择 ID
【发布时间】:2018-07-30 15:45:35
【问题描述】:

您好,我有以下问题。

我有一张类似sql fiddle 的桌子 该表定义了一个关系,它包含来自其他两个表的 ID

示例值

| FirstID  | SecondID  | 
|  1       |     1     |
|  1       |     2     |
|  1       |     3     |
|  2       |     1     |
|  2       |     2     |
|  2       |     3     |
|  2       |     4     |
|  2       |     5     |
|  3       |     1     |
|  3       |     2     |
|  3       |     3     |

我想选择所有满足以下条件的 FirstID。 它们对应的 SecondID 在 1-3 范围内,而不是在 4-5 范围内

例如,在这种情况下,我们需要 FirstID 1 和 3。

我尝试了以下查询

SELECT FirstID from table 
WHERE SecondID IN (1,2,3) AND SecondID NOT IN (4,5)

SELECT  FirstID,SecondID
FROM(
   SELECT FirstID, SecondID
   FROM  table
   WHERE  SecondID in (1,2,3,4,5) ) 
WHERE SecondID NOT IN (4,5)

但我没有得到我想要的正确结果。

获取我想要的数据的正确查询是什么?

【问题讨论】:

  • @Eric 我得到了错误的结果。我已经编辑了问题。

标签: sql


【解决方案1】:
SELECT FirstID
FROM table
WHERE SecondId in (1,2,3) --Included values
AND FirstID NOT IN (SELECT FirstID FROM test
                    WHERE SecondId IN (4,5)) --Excluded values

【讨论】:

    【解决方案2】:

    min()max() 怎么样:

    select firstid
    from t
    group by firstid
    having min(secondId) between 1 and 3 and
           max(secondid) between 1 and 3;
    

    假设 1 是最小值,那么这可以简化为:

    having max(secondid) <= 3;
    

    对于任意范围,你可以使用sum(case):

    having sum(case when secondId between 1 and 3 then 1 else 0 end) > 0 and
           sum(case when secondId between 4 and 5 then 1 else 0 end) = 0;
    

    【讨论】:

    • 感谢您的快速回复:)。不能保证 SecondID 是连续的或在一定范围内。上述值只是示例值。可能是我们希望 FirstIDs 具有对应的 SecondIDs 1,10, 56 而不是 5, 30
    • @Corcus 。 . .我增强了答案。
    【解决方案3】:

    我认为 Gonzalo Lorieto 可能已经对这个问题给出了最好的答案,但是根据您的数据大小,WHERE 子句中的 SELECT 语句可能会变得非常慢,而下面的语句可能会明显更快(尽管目前尚不清楚是否值得降低可读性...)

    SELECT inrange.FirstId FROM 
    t inrange
    LEFT OUTER JOIN 
    (SELECT FirstID FROM t
    WHERE SEcondId IN (4,5)) outrange
    ON inrange.firstID = outrange.firstId
    WHERE SecondID IN (1,2,3)
    AND outrange.firstId IS NULL
    GROUP BY inrange.FirstId
    

    【讨论】:

      【解决方案4】:

      您将需要使用EXISTS 子句来排除具有无效 SecondID 的 FirstID。这是一个例子:

      SELECT FirstID from test Has123
      WHERE SecondID IN (1,2,3)
      AND NOT EXISTS (
        SELECT 1 FROM test Not45 
        WHERE Has123.FirstID = Not45.FirstID 
        AND Not45.SecondID IN (4,5)
      )
      GROUP BY FirstID
      

      SqlFiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-22
        • 2013-08-01
        相关资源
        最近更新 更多