合并所有子查询中的结果

时间:2019-07-12 06:19:34

标签: sql postgresql

我有一个postgre表,其表述与下面的数据类似。

餐具表:

-----------------------
| Name    | Option     |
-----------------------
| jane    | social      |
| jane    | vegan       |
| jane    | gmo-free    |
| jane    | italian     |
| jack    | social      |
| jack    | corporate   |
| jack    | gmo-free    |
| jack    | greek       |
| rodz    | social      |
| rodz    | wedding     |
| rodz    | gmo-free    |
| rodz    | vegan       |
| rodz    | french      |

这是我要运行的“伪”查询

SELECT * FROM caters 
WHERE option is either ['italian', 'french'] 
AND WHERE option is both ['wedding', 'social']

此伪查询应返回rodz。因为它有意大利或法国特色,并且既有婚礼又有社交。

这是我尝试编写以完成我的sudo查询的查询

SELECT c.name FROM caters c
WHERE c.option in ('italian', 'french')
GROUP BY c.name
HAVING array_agg(c.option) @> array['wedding', 'social']

但是,这没有任何结果。单独运行查询

SELECT c.name FROM caters c
WHERE c.option in ('italian', 'french')
GROUP BY c.name

结果:

-----------
| Name    |
-----------
| jane    | // has italian
| rodz    | // has french

另一个查询

SELECT c.name FROM caters c
GROUP BY c.name
HAVING array_agg(c.option) @> array['wedding', 'social']

结果:

-----------
| Name    |
-----------
| rodz    | // has wedding and social

所以我可以单独查看查询是否正确。如果我有2个查询给我正确的结果,这使我想得很好,只需要过滤掉两个查询中的结果,为什么不JOIN

所以我尝试了

SELECT c.name FROM caters c
JOIN caters c1 
ON c1.name = c.name and c1.option = c.option
WHERE c1.option in ('italian', 'french')
GROUP BY c.name
HAVING array_agg(c.option) @> array['wedding', 'social']

但这也没有结果。知道我该怎么做吗?

注意:每次查询运行时,查询都是动态的,有时可能是5种语言,有时是2种语言,例如在本示例('italian', 'french')中。举个例子,我所说的动态查询就是另一个查询

SELECT * FROM caters 
WHERE option is either ['italian'] 
AND WHERE option is both ['corporate', 'social']
// returns none
----------------------------------------------------------
SELECT * FROM caters 
WHERE option is either ['french', 'greek'] 
AND WHERE option is either ['gmo-free', 'vegan'] 
AND WHERE option is both ['corporate', 'social']
// returns jack
----------------------------------------------------------
SELECT * FROM caters WHERE option is ['social']
// returns jack, and rodz

2 个答案:

答案 0 :(得分:1)

您可以尝试使用相关子查询

DEMO

select distinct name from tablename a 
where option in ('italian', 'french') and exists
(
  select 1 from tablename b where a.name=b.name and option in ('wedding', 'social')
  group by b.name having count(distinct option)=2
)

输出:

name
rodz

答案 1 :(得分:0)

这是一种方法:

SELECT c.name
FROM caters c
WHERE c.option in ('italian', 'french', 'wedding', 'social')
GROUP BY c.name
HAVING COUNT(*) FILTER (WHERE c.option IN ('italian', 'french')) >= 1 AND
       COUNT(*) FILTER (WHERE c.option IN ('wedding', 'social')) = 2;