简体   繁体   English

PostgreSQL,混合食物和食谱

[英]PostgreSQL, mixed food and recipes

Before some time I had a problem which seem's to be solved but it is not so I have to explain it better and support with more suitable tables: 前一段时间我有一个问题,这似乎对需要解决,但它不是,所以我要解释它更好和支持更适合表:

DROP TABLE IF EXISTS usedfood;  
CREATE TABLE usedfood 
   (food_code int, food_name text, qtyu integer, meas text);
INSERT INTO usedfood (food_code, food_name, qtyu, meas)
VALUES (10,  'spaghetti',        3, 'pcs'),
       (156, 'mayonnaise',       2, 'pcs'),
       (173, 'ketchup',          1, 'pcs'),
       (172, 'bolognese sauce',  2, 'pcs'),
       (173, 'ketchup',          1, 'pcs'),
       (175, 'worchester sauce', 2, 'pcs'),
       (177, 'parmesan',         1, 'pcs'),
       (10,  'spaghetti',        2, 'pcs'),
       (156, 'mayonnaise',       1, 'pcs');

DROP TABLE IF EXISTS ingredients;
CREATE TABLE ingredients
   (food_code int, ingr_code int, ingr_name text, qtyi decimal(11,3), meas text);
INSERT INTO ingredients (food_code, ingr_code, ingr_name, qtyi, meas)
VALUES (10,  1256, 'spaghetti rinf', 75, 'gramm'),
       (156, 1144, 'salt',          0.3, 'gramm'),
       (10,  1144, 'salt',          0.5, 'gramm'),
       (156, 1140, 'fresh egg',      50, 'gramm'),
       (172, 1138, 'tomato',         80, 'gramm'),
       (156, 1139, 'mustard',         5, 'gramm'),
       (172, 1136, 'clove',           1, 'gramm'),
       (156, 1258, 'oil',           120, 'gramm'),
       (172, 1135, 'laurel',        0.4, 'gramm'),
       (10,  1258, 'oil',           0.4, 'gramm'),
       (172, 1130, 'corned beef',    40, 'gramm');

Those two tables represent a list of food and list of ingredients used in SOME food. 这两张表代表了食品清单和某些食品中使用的成分清单。
However, some food haven't ingredients (and that is a prolem). 然而,一些食物没有成分(这是一个问题)。

This query count and list usage of ingredients by list of food where food and ingredients are logically connected by 'food_code': 此查询计算并列出食品清单中食材和成分通过'food_code'逻辑连接的食品清单的使用情况:

SELECT SUM(f.qtyu) AS used_times,
       COALESCE(i.ingr_code, MAX(f.food_code)) AS code,
       COALESCE(i.ingr_name, MAX(f.food_name)) AS f_name,
       SUM(COALESCE(i.qtyi, 1) * f.qtyu)::decimal(11,3) AS qty,
       COALESCE(max(i.meas), max(f.meas)) AS meas
  FROM usedfood f LEFT JOIN ingredients i
    ON f.food_code = i.food_code
 GROUP BY i.ingr_code, i.ingr_name

But here is issue that all food which haven't ingredients is grouped together instead of by code and is listed as one food. 但问题在于,所有没有成分的食物都被分组在一起而不是按照代码被列为一种食物。 This is not wanted and I would like that some find and solve that problem to get this result from given tables: 这不是想要的,我希望有些人能够从给定的表中找到并解决这个问题:

 2   173 ketchup            2.000 pcs
 1   175 parmesan           1.000 pcs
 2   177 worchester sauce   2.000 pcs
 8  1144 salt               3.400 gramm
 3  1140 fresh egg        150.000 gramm
 2  1138 tomato           160.000 gramm
 8  1258 oil              362.000 gramm
 2  1135 laurel             0.800 gramm
 5  1256 spaghetti rinf   375.000 gramm
 2  1130 corned beef       80.000 gramm
 3  1139 mustard           15.000 gramm
 2  1136 clove              2.000 gramm

Try to put subquery in from, so that is easier to you to group columns without conditionally selecting two values: 尝试将子查询放入,这样您就可以更轻松地对列进行分组而无需有条件地选择两个值:

SELECT sum(temp.used_times), temp.code, temp.f_name, sum(temp.qty), max(temp.meas)
FROM (SELECT f.qtyu AS used_times,
             COALESCE(i.ingr_code, f.food_code) AS code,
             COALESCE(i.ingr_name, f.food_name) AS f_name,
             (COALESCE(i.qtyi, 1) * f.qtyu)::decimal(11,3) AS qty,
             COALESCE(i.meas, f.meas) AS meas
      FROM usedfood f LEFT JOIN ingredients i
      ON f.food_code = i.food_code) as temp
GROUP BY temp.code, temp.f_name
ORDER BY temp.code

Are you looking for this? 你在找这个吗?

SELECT SUM(f.qtyu) AS used_times,
       COALESCE(i.ingr_code, f.food_code) AS code,
       COALESCE(i.ingr_name, f.food_name) AS f_name,
       SUM(COALESCE(i.qtyi, 1) * f.qtyu)::decimal(11,3) AS qty,
       COALESCE(i.meas, f.meas) AS meas
  FROM usedfood f LEFT JOIN ingredients i
    ON f.food_code = i.food_code
 GROUP BY COALESCE(i.ingr_code, f.food_code), 
          COALESCE(i.ingr_name, f.food_name),
          COALESCE(i.meas, f.meas)
 ORDER BY code;

Output: 输出:

| USED_TIMES | CODE |           F_NAME | QTY |  MEAS |
|------------|------|------------------|-----|-------|
|          2 |  173 |          ketchup |   2 |   pcs |
|          2 |  175 | worchester sauce |   2 |   pcs |
|          1 |  177 |         parmesan |   1 |   pcs |
|          2 | 1130 |      corned beef |  80 | gramm |
|          2 | 1135 |           laurel | 0.8 | gramm |
|          2 | 1136 |            clove |   2 | gramm |
|          2 | 1138 |           tomato | 160 | gramm |
|          3 | 1139 |          mustard |  15 | gramm |
|          3 | 1140 |        fresh egg | 150 | gramm |
|          8 | 1144 |             salt | 3.4 | gramm |
|          5 | 1256 |   spaghetti rinf | 375 | gramm |
|          8 | 1258 |              oil | 362 | gramm |

Here is SQLFiddle demo 这是SQLFiddle演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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