【问题标题】:Select records based on column priority根据列优先级选择记录
【发布时间】:2012-08-08 11:01:47
【问题描述】:

首先,这个问题的标题很糟糕,但我没有找到更好的方式来描述我的问题。

可能有一种非常简单的方法可以做到这一点,但我想不通。这与this 问题非常相似,但我在 sqlite3 (iOS) 上运行,所以我怀疑我的选择要有限得多。

我有一张包含产品记录的表格。所有记录都有一个 ID(注意:我说的不是行 ID,而是每个产品唯一的标识号)。某些产品可能在表中有两个条目(都具有相同的 ID)。唯一的区别在于一个特殊的列(假设列 COLOR 可以是 RED 或 GREEN)。

我想要做的是根据 COLOUR 的值创建一个独特产品列表,如果同一产品同时存在 GREEN 和 RED 记录,则优先级为 GREEN。

简而言之,如果我有以下情况:

id       PRODUCT ID    COLOUR
1        1001          GREEN
2        1002          GREEN
3        1002          RED
4        1003          RED

我希望我的 SELECT 返回第 1、2 和 4 行。我怎样才能做到这一点?

我目前的方法是有单独的表,并手动进行连接,但显然这是一个非常糟糕的主意..

注意:我尝试使用与 here 相同的方法:

SELECT * 
  FROM xx
 WHERE f_COLOUR = "GREEN"
UNION ALL
SELECT * 
  FROM xx 
 WHERE id not in (SELECT distinct id 
                    FROM xx 
                   WHERE f_COLOUR = "GREEN");

但我得到的结果是第 1,2,3,4 行,而不仅仅是 1,2,4。我错过了什么?

编辑:请再问一个问题:如何使它适用于记录子集,即。如果我想过滤一些记录而不是整个表?

例如,如果我有类似 SELECT * FROM table WHERE productID LIKE "1%" ... 我如何检索每个唯一产品,但仍尊重颜色优先级 (GREEN>RED)?

【问题讨论】:

    标签: sql sqlite select


    【解决方案1】:

    您的查询几乎是正确的。只需使用PRODUCTID 而不是ID

    SELECT * 
    FROM xx
    WHERE f_COLOUR = "GREEN"
    UNION
    SELECT * 
    FROM xx 
    WHERE PRODUCTID not in 
                    (SELECT PRODUCTID
                     FROM xx 
                     WHERE f_COLOUR = "GREEN");
    

    SQLFiddle Demo

    【讨论】:

    • + 1 你秒杀我 =)
    • 啊。谢谢 :)。就速度而言,这是一个好方法吗?我的表可能有 100,000 多条记录。
    【解决方案2】:

    试试这个

    SELECT * 
    FROM xx
    WHERE COLOUR = 'GREEN'
    UNION
    SELECT * 
    FROM xx WHERE P_Id not in 
                    (SELECT P_Id
                     FROM Persons 
                     WHERE COLOUR = 'GREEN');
    

    See ALSO SQL FIDDLE DEMO

    【讨论】:

    • 呵呵。尝试将 sqlfiddle 示例中使用的服务器更改为 sqlite web :) +1
    【解决方案3】:

    我只是想提出,您可以通过以下方式与组一起执行此操作:

    select (case when sum(case when colour = 'Green' then 1 else 0 end) > 0
                 then max(case when colour = 'Green' then id end)
                 else max(case when colour = 'Red' then id end)
            end) as id,
           product_id
           (case when sum(case when colour = 'Green' then 1 else 0 end) > 0 then 'Green'
                 else 'Red'
            end) as colour
    from t
    group by product_id
    

    【讨论】:

    • 感谢 Gordon,但它不起作用,它会选择所有记录。见this
    • 当我查看数据时,我没有意识到“id”在每一行都是唯一的。无论如何,这只是一种选择。
    【解决方案4】:

    你可以这样拥有它

    WITH PriorityTable
    AS
    (
        SELECT T.*,
            ROW_NUMBER() OVER (PARTITION BY T.ID
                                ORDER BY PT.ColorPriority )  PriorityColumn
        FROM XX AS T
        INNER JOIN (
            SELECT 'RED' AS f_COLOUR , 1 AS ColorPriority
            UNION
            SELECT 'GREEN' AS f_COLOUR , 2 AS ColorPriority
        ) AS PT
            ON T.f_COLOUR  = PT.f_COLOUR 
    )
    
    SELECT * FROM PriorityTable
    WHERE PriorityColumn = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      相关资源
      最近更新 更多