[英]MySQL to PostgreSQL - Find in array, and count array values
我有一个colors
表和一个items
表,这两个表之间存在多对多关系(通过items_colors
表)。 一个项目可以有多个 colors,一个颜色可以有多个项目。
items
id
colors
id
name
items_colors
item_id [foreign key: items(id)]
color_id [foreign key: colors(id)]
我目前正在从MySQL迁移到PostgreSQL 。 下面的这个 SQL 查询与 MySQL 配合良好,但我无法使其在 PostgreSQL 上工作:
SELECT i.*
FROM
items i
JOIN items_colors ic ON ic.item_id = i.id
JOIN colors c ON c.id = ic.color_id
GROUP BY i.id
HAVING COUNT(*) = SUM( c.name IN ('green', 'blue') )
A 也试图以不同的方式表达HAVING
:
HAVING SUM( c.name NOT IN ('green', 'blue') ) = 0;
在所有情况下,使用 PostgreSQL 我都会收到此错误:
Query 1 ERROR: ERROR: function sum(boolean) does not exist
LINE 7: HAVING COUNT(*) = SUM( c.name IN ('green'...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
(仅出于此查询的上下文和目标,我想获取仅匹配一个或多个提供的 colors (来自提供的颜色数组)的所有项目。如果项目还与未指定的附加颜色相关联数组,它不应该被检索.在我上面的例子中,我得到所有与给定数组匹配的项目,所以所有项目都有绿色,或蓝色,或绿色和蓝色.但是如果一个项目有蓝色和红色 colors(或只有红色,或没有颜色),它被排除在结果之外。)
这应该在 Postgres 中工作,假设items.id
是主键:
SELECT i.*
FROM items i JOIn
items_colors ic
ON ic.item_id = i.id JOIN
colors c
ON c.id = ic.color_id
GROUP BY i.id
HAVING COUNT(*) = SUM( (c.name IN ('green', 'blue'))::INT );
或者:
HAVING COUNT(*) = COUNT(*) FILTER (WHERE c.name IN ('green', 'blue'))
适用于两个数据库的版本是:
HAVING COUNT(*) = SUM(CASE WHEN c.name IN ('green', 'blue') THEN 1 ELSE 0 END);
我会看一下 PostgreSQL 中的数组运算符:
SELECT i.*
FROM
items i
JOIN items_colors ic ON ic.item_id = i.id
JOIN colors c ON c.id = ic.color_id
GROUP BY i.id
HAVING ARRAY_AGG(c.name) <@ ARRAY['green', 'blue'];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.