根据列优先级选择记录

时间:2012-08-11 09:43:47

标签: sql sqlite select

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

这可能是一种非常简单的方法,但我无法理解。这与this问题非常相似,但我在sqlite3(iOS)上运行,所以我怀疑我的选项更加有限。

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

我想要做的是根据COLOR的值创建一个独特产品列表,如果同一产品同时存在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%”......我如何检索每个独特的产品,但仍然尊重颜色优先级(绿色> RED)?

4 个答案:

答案 0 :(得分:5)

您的查询几乎正确无误。只需使用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 :(得分: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

答案 2 :(得分:0)

我只是想提出你可以通过以下方式与小组合作:

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

答案 3 :(得分:0)

你可以这样做

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