我有2张桌子。
表1“广告”:
id | 描述 | 状态 |
---|---|---|
1 | 广告号1 | 活跃 |
2 | 广告号2 | 活跃 |
表2“ads_features”:
id | 广告 | 特点 |
---|---|---|
1 | 1 | 特点1 |
2 | 1 | 特点2 |
我需要一个 SQL 函数,该函数将从 1 返回值,并使用表 2 中的值添加新列。但是,如果在表 2 中找到函数参数“features”(类型数组)中的所有项目,则应仅返回值。这是我的内容到目前为止:
CREATE OR REPLACE FUNCTION filter_ads(features text[] default NULL)
RETURNS table (
id uuid,
description text,
status text,
ads_features text[]
)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN QUERY
SELECT
ads.*,
ARRAY(
SELECT featuresTable.feature
FROM ads_features featuresTable
WHERE featuresTable.ad = ads.id
) AS ads_features
FROM ads
WHERE
(ads.status = 'active') AND
features IS NULL OR COALESCE(features, '{}'::text[]) = '{}'::text[] OR EXISTS(
SELECT 1
FROM ads_features featuresTable
WHERE (featuresTable.ad = ads.id) AND
(featuresTable.feature = ANY(features))
);
END;
$$;
问题是,如果我传递“[feature 1, feature 3]”作为参数,函数仍然会返回 ID 为 1 的广告,因为满足 ANY 运算符。但我想在表 2 中仅找到所有数组项时返回记录。如果我使用 ALL 运算符,它根本不起作用。我得到的记录为零。
预期结果:
场景一:
select * from filter_ads(ARRAY(“feature 1”, “feature 2”))
id | 描述 | 状态 | 广告功能 |
---|---|---|---|
1 | 广告号1 | 活跃 | [功能1、功能2] |
场景2:
select * from filter_ads(ARRAY(“feature 1”, “feature 3”))
No records found
基本上,这是过滤功能的一部分,用户将在 UI 中的许多复选框中进行选择,然后将显示符合所有条件的记录。
feature
仅包含一个值。您需要该广告的所有功能的数组。 group by ad
并将其所有特征聚合到一个数组中 array_agg
。
having
约束聚合,并使用 @>
检查一个数组是否包含另一个数组。
select
ads.*,
array_agg(feature) as features
from ads
join ads_features
on ads.id = ads_features.ad
where ads.status = 'active'
group by ads.id
having array_agg(feature) @> array['feature2', 'feature1']
示范.