繁体   English   中英

MySQL 到 PostgreSQL - 在数组中查找并计算数组值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM