2014-01-09 84 views
3

一段时间,我有一个problem这似乎对需要解决,但它不是,所以我要解释它更好,支持更合适的表格之前:PostgreSQL的,混合的食物和食谱

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'); 

这两个表代表一些食物和一些食物中使用的成分列表。
但是,一些食物没有成分(这是一个问题)。

由地方食品及配料在逻辑上由“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 

但这里的问题是还没有成分组合在一起的所有食品而不是通过代码,并被列为一种食物。这不是想要的,我想,一些发现和解决这个问题,从给定的表得到这样的结果:

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 

回答

1

您是否正在寻找?

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; 

输出:

 
| 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 | 

这里是SQLFiddle演示

+0

确切的说,谢谢你的工作和预期的一样。 –

1

试图把子查询从,所以这是比较容易,你来为列,而不有条件选择两个值:

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 
+0

谢谢partlov,您的解决方案也给出了不错的结果,对大数据也许只是慢一点。 –