我需要一些SQL查询的帮助。让我来描述一下场景
我有三个表,dispensaries
,goods
和products
。
products
条记录有两个fk
,good_id
和dispensary_id
,可让我通过产品从药房访问商品。
商品还有一个名为name
现在我要解决的问题如下:
对于提供的一组商品名称([good_name1, good_name2, etc]
),我想获得所有包含所有商品的药房(与这些商品相匹配的商品)。
让我举一个例子:
good1 whose names is good_1 belongs to dispensary1
good1 whose names is good_1 belongs to dispensary2
good2 whose names is good_2 belongs to dispensary1
所以我需要创建一个SQL查询,其中提供的商品数组[good1, good2]
仅返回dispesary1
提前致谢。
答案 0 :(得分:0)
您可能希望将其转换为一个函数,该函数接受您所追求的goods.name项的数组。首先,我会得到正确的数据语法和格式。在查询窗口中尝试以下操作,看看它是否通过静态商品列表中的文本项获取了您想要的数据。
SELECT dispensary.id, dispensary.name
FROM products
LEFT JOIN goods ON goods.id = products.goods_id
LEFT JOIN dispensary ON dispensary.id = products.dispensary_id
WHERE goods.name IN ([good_name1, good_name2, etc])
AND dispensary.id IS NOT NULL;
修改
只返回带有数组中所有项目的药房,尝试(来自@ErwinBrandstetter的修改参考回答PostgreSQL where all in array):
CREATE OR REPLACE FUNCTION f_dispensaries_with_all_products(_user_arr string[])
RETURNS SETOF dispensary AS
$BODY$
DECLARE
_sql text := '
SELECT d.*
FROM products p
JOIN dispensary d ON d.id = p.dispensary_id';
i int;
BEGIN
FOREACH i IN ARRAY _user_arr LOOP
_sql := _sql || '
JOIN goods g' || i || ' ON g|| i || '.id = p.good_id';
END LOOP;
_sql := _sql || '
WHERE d.id IS NOT NULL ';
FOREACH i IN ARRAY _user_arr LOOP
_sql := _sql || '
AND g' || i || '.name = ' || _user_arr[i];
END LOOP;
-- RAISE NOTICE '%', _sql;
RETURN QUERY EXECUTE _sql;
END;
$BODY$ LANGUAGE plpgsql VOLATILE;
答案 1 :(得分:0)
实现这一目标的一种方法是使用INTERSECT
,为每个子句生成一个集合 - 这意味着您必须将列表展开到 n 查询中,每个项目一个:
SELECT dispensary.id, dispensary.name
FROM products
INNER JOIN goods ON goods.id = products.goods_id
INNER JOIN dispensary ON dispensary.id = products.dispensary_id
WHERE goods.name = 'good_1'
INTERSECT
SELECT dispensary.id, dispensary.name
FROM products
INNER JOIN goods ON goods.id = products.goods_id
INNER JOIN dispensary ON dispensary.id = products.dispensary_id
WHERE goods.name = 'good_2'
INTERSECT
SELECT dispensary.id, dispensary.name
FROM products
INNER JOIN goods ON goods.id = products.goods_id
INNER JOIN dispensary ON dispensary.id = products.dispensary_id
WHERE goods.name = 'good_3'
这样,您只会获得所有集合中的结果。