SQL选择列表关系为表

时间:2017-11-11 08:52:31

标签: sql postgresql

Postgres数据库有3个表:

recipes(id,recipe_name)
ingredients(id,ingredient_name)
recipes_ingredients(recipe_id,ingredient_id)

有没有办法编写一个动态sql选择,它会为配料表中的每个成分创建一个配方列表,如果它与配方相关,则为是?

像:

+---------------+-------------------+-------------------+-----+
|  recipe_name  | ingredient_name 1 | ingredient_name 2 |  …  |
+---------------+-------------------+-------------------+-----+
| recipe_name 1 | yes               |                   |     |
| recipe_name 2 |                   | yes               |     |
| recipe_name 3 | yes               |                   | yes |
+---------------+-------------------+-------------------+-----+

让它显示0或1确定但是有一种简单的方法可以让它变得动态,所以我不必更新配料表中的每一项吗?

SELECT 
DISTINCT r.recipe_name,
(SELECT COUNT(*) FROM recipes_ingredients WHERE ingredient_id = 1 AND recipe_id = ri.recipe_id) as Tomato,
(SELECT COUNT(*) FROM recipes_ingredients WHERE ingredient_id = 2 AND recipe_id = ri.recipe_id) as Mustard,
(SELECT COUNT(*) FROM recipes_ingredients WHERE ingredient_id = 3 AND recipe_id = ri.recipe_id) as Cucumber,
(SELECT COUNT(*) FROM recipes_ingredients WHERE ingredient_id = 4 AND recipe_id = ri.recipe_id) as Flour
FROM recipes r
INNER JOIN recipes_ingredients ri on ri.recipe_id = r.id
INNER JOIN ingredients i on i.id = ri.ingredient_id
ORDER BY r.recipe_name

2 个答案:

答案 0 :(得分:0)

按recipe_name分组,然后选择case max ingredient_name,其中ingredient_name =成分 像这样的东西

SELECT 
r.recipe_name,
CASE WHEN MAX(i.ingredient_name) = 'Tomato' THEN 'Yes' ELSE 'No' END as Tomato
FROM recipes_ingredients ri
INNER JOIN recipes r on r.id = ri.recipe_id
INNER JOIN ingredients i on i.id = ri.ingredient_id
GROUP BY r.recipe_name

病例会随着您的成分数增加而增长。

或者您可以尝试使用SQL pivot来实现更准确的交叉表功能

答案 1 :(得分:0)

你需要的是postgresql中的bb mssql。对于动态sql解决方案,请参阅此帖子(这对我来说最合适):http://www.cureffi.org/2013/03/19/automatically-creating-pivot-table-column-names-in-postgresql/,其他选项,请参阅此问题:Dynamically generate columns for crosstab in PostgreSQL