有一个Postgres数据库,该表有三列。数据结构在外部系统中,所以我无法对其进行修改。
每个对象都由三行表示(由列element_id
标识-该列中具有相同值的行表示同一对象),例如:
key value element_id
-----------------------------------
status active 1
name exampleNameAAA 1
city exampleCityAAA 1
status inactive 2
name exampleNameBBB 2
city exampleCityBBB 2
status inactive 3
name exampleNameCCC 3
city exampleCityCCC 3
在查询中,我想放置一些名称的列表,检查同一对象中带有key
列status
的行的值是否为'active'并返回此对象的名称仅当状态为“有效”时。
因此,在此示例中,数据库表中包含三个对象。我想在查询中输入两个“名称”:
a)exampleNameAAA
b)exampleNameCCC
,结果应为:
exampleNameAAA
(因为我要了两个对象,而其中只有一个在active
行中具有status
值。
答案 0 :(得分:0)
一个选项使用聚合:
SELECT
MAX(CASE WHEN "key" = 'name' THEN "value" END) AS name
FROM yourTable
GROUP BY element_id
HAVING
MAX(CASE WHEN "key" = 'name' THEN "value" END) IN
('exampleNameAAA', 'exampleNameCCC') AND
SUM(CASE WHEN "key" = 'status' AND "value" = 'active' THEN 1 ELSE 0 END) > 0;
name
exampleNameAAA
这是关键方法,其中我们为每个element_id
组隔离了单独的键和值。
答案 1 :(得分:0)
您可以使用EXISTS查询:
select e1.*
from element e1
where (e1.key, e1.value) in ( ('name', 'exampleNameAAA'), ('name', 'exampleNameCCC'))
and exists (select *
from element e2
where e2.element_id = e1.element_Id
and (e2.key, e2.value) = ('status', 'active'));
答案 2 :(得分:0)
我喜欢这样表达:
SELECT MAX(t.value) FILTER (WHERE t.key = 'name') AS name
FROM t
GROUP BY t.element_id
HAVING MAX(t.value) FILTER (WHERE t.key = 'name') IN ('exampleNameAAA', 'exampleNameCCC') AND
MAX(t.value) FILTER (WHERE t.key = 'status') = 'active';
总而言之,在这种情况下,exists
解决方案的性能可能更高。聚合方法的优点在于,您可以轻松地将其他列(例如城市)引入select
中。
SELECT MAX(t.value) FILTER (WHERE t.key = 'name') AS name,
MAX(t.value) FILTER (WHERE t.key = 'city') as city
(注意:key
是列的坏名称,因为它是SQL关键字。)