例如,假设我有一个包含两列X
和Y
. 现在我想select
从这个表中得到一些具有以下规则的行:
- 将“组”定义为具有相同列值的一组行
Y
。 - 从一个组中,只选择一行。
- 在组中,如果其中一个行具有
X=a
预定义的 a,则从该组中选择该行。 - 在一个组中,如果没有行有
X=a
,则可以选择任何行。
在单个 SQL 查询中执行此操作的选项有哪些?
例如,假设我有一个包含两列X
和Y
. 现在我想select
从这个表中得到一些具有以下规则的行:
Y
。X=a
预定义的 a,则从该组中选择该行。X=a
,则可以选择任何行。在单个 SQL 查询中执行此操作的选项有哪些?
试试这个:
SELECT DISTINCT
t1.Y,
COALESCE(a2.x, a1.x) 'x'
FROM Tablename t1
LEFT JOIN
(
SELECT Y, MIN(x) x
FROM Tablename
GROUP BY Y
) a1 ON t1.Y = a1.Y
LEFT JOIN
(
SELECT Y, MIN(x) x
FROM Tablename
WHERE x = 'a'
GROUP BY Y
) a2 ON t1.Y = a2.Y;
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;
CREATE TABLE yx
( Y INTEGER NOT NULL
, x CHAR NOT NULL
, PRIMARY KEY (y,x)
);
INSERT INTO yx (y,x) VALUES
(10,'b') ,(10,'d') ,(10,'e' ) -- y==10 does not have an 'a'
,(20,'b') ,(20,'a') ,(20,'d') -- y==20 does have an 'a'
;
--
-- using a CTE
--
WITH this AS (
SELECT y,x
, row_number() OVER (PARTITION by y ORDER BY (x='a') DESC, x ASC) AS rnk
FROM yx
)
SELECT this.y,this.x
FROM this
WHERE this.rnk = 1
;
--
-- with a subselect instead of a CTE
--
SELECT this.y,this.x
FROM (
SELECT y,x
, row_number() OVER (PARTITION by y ORDER BY (x='a') DESC, x ASC) AS rnk
FROM yx
) this
WHERE this.rnk = 1
;