2014-01-09 83 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,您的解決方案也給出了不錯的結果,對大數據也許只是慢一點。 –