2016-12-31 49 views
-1

的參數n個粗略地講,美國農業部營養數據庫的結構是這樣的:查詢在SQL

+---------+--------+ 
| food_id | name | 
+---------+--------+ 
|  1 | butter | 
|  2 | bacon | 
|  3 | eggs | 
+---------+--------+ 

+---------+-----------+----------------+ 
| food_id | per_100_g | description_id | 
+---------+-----------+----------------+ 
|  1 |  20 |    1 | 
|  1 |  10 |    2 | 
|  2 |  30 |    1 | 
|  2 |  70 |    2 | 
|  3 |  10 |    1 | 
|  3 |  80 |    2 | 
+---------+-----------+----------------+ 

+----------------+-------------+ 
| description_id | description | 
+----------------+-------------+ 
|    1 | fat   | 
|    2 | protein  | 
+----------------+-------------+ 

我是新來編寫SQL。我可以編寫一個結合了所有三個表格的連接,並且我可以根據單個參數進行查詢,例如食物具​​有多少脂肪。但是有沒有一種方法可以查詢多少脂肪和一個食物有多少蛋白質per_100_g?我知道這有點主觀,但我希望能從中學到一些東西。謝謝!

我的數據庫是postgres。理想情況下,這可能是一個解決方案,可以擴展到n個營養標準和n個組合,例如,一個食物含有多少脂肪,蛋白質和鈉或多少維生素C,K和鉀 - 編寫幾千個查詢的變體。

編輯:

示例查詢我寫的,但只能找到單一的營養數據是這樣的:

select des.long_desc 
    from food_des des 
    inner join nut_data fat 
     on des.ndb_no = fat.ndb_no 
    inner join nutr_def fat_des 
     on fat.nutr_no = fat_des.nutr_no 
    where (fat_des.tagname = 'FAT') and (fat.nutr_val < 10) 

編輯2:

我期待着與脂肪從查詢結果少比30和蛋白質超過10來返回這個過濾結果

+---------+-------+-----------+---------------+ 
| food_id | name | fat_value | protein_value | 
+---------+-------+-----------+---------------+ 
|  2 | bacon |  30 |   70 | 
|  3 | eggs |  10 |   80 | 
+---------+-------+-----------+---------------+ 
+2

你嘗試過什麼嗎? –

+0

對不起,請參閱編輯^ – motleydev

+0

提示SUM ..LEFT JOIN..GROUP BY..HAVING – Mihai

回答

1

你可以做一些像這樣的東西來尋找食物與多種營養素:

SELECT f.* 
FROM foods f 
INNER JOIN food_ingredients i 
ON f.food_id = i.food_id 
INNER JOIN descriptions d 
ON i.description_id = d.description_id 
GROUP BY f.food_id, f.NAME 
HAVING sum(CASE WHEN d.description = 'FAT' THEN per_100_g ELSE 0 END) = 10 
AND sum(CASE WHEN d.description = 'Protein' THEN per_100_g ELSE 0 END) = 20; 

Having部分可以很容易地擴展,以支持更多的過濾器。

+0

這看起來像我在找什麼。我不知道你的postgres能力在哪裏,但是你知道你是否可以編寫一個程序來返回一個單一的條件,然後結合多個程序來獲得相同的結果?我正試圖學習最「可持續」的方式來增加項目的靈活性。 – motleydev

1

也許是這樣的:

select 
    f.name, 
    j.fat_per_100_g, 
    j.protein_per_100_g 
from 
    foods f 
    inner join (
     select 
      i.food_id, 
      sum(case when d.description = 'fat' then 
       i.per_100_g else null end) as fat_per_100_g, 
      sum(case when d.description = 'protein' then 
       i.per_100_g else null end) as protein_per_100_g 
     from 
      ingredients i 
      inner join descriptions d 
      on i.description_id = d.description_id 
     group by 
      i.food_id 
     ) j 
    on f.food_id = j.food_id 
where 
    j.fat_per_100_g < 30 and 
    j.protein_per_100_g > 10 
; 

    name | fat_per_100_g | protein_per_100_g 
------------+---------------+------------------- 
eggs  |   10 |    80 

附:培根有30個fat_per_100_g,所以如果脂肪必須少於30g,它纔會被返回。