2012-06-26 32 views
0

選擇最觀看項通過標籤的名字,我有2個表:itemsitems_purchasedtag名稱和其他描述性信息位於items表格中,每個項目的採購數量保存在items_purchased表格中。 item_id上的表格是JOIN與MySQL

這裏是我的查詢到目前爲止:

(select *, sum(purchaseyesno) as tots from items join items_purchased on items.item_id=items_purchased.item_id where tag = 'History' and deleted!=1 and pub_priv!=1 order by tots desc limit 1) 
UNION ALL 
(select *, sum(purchaseyesno) as tots from items join items_purchased on items.item_id=items_purchased.item_id where tag = 'Medicine' and deleted!=1 and pub_priv!=1 order by tots desc limit 1) 
UNION ALL 
(select *, sum(purchaseyesno) as tots from items join items_purchased on items.item_id=items_purchased.item_id where tag = 'Biology' and deleted!=1 and pub_priv!=1 order by tots desc limit 1) 
//... more tags (20 in all) would follow 

的問題是,與某些標籤的物品尚未所以查詢拋出的Column "item_id" cannot be null錯誤購買。

這裏的示例表:

  items    |  items_purchased | 
    item_id tag  title  | item_id purchaseyesno| 
    1  Biology DNA is cool | 1   1  | 
    2  Medicine Doctors | 2   1  | 
    3  Law Laws are cool| 4   1  |  
    4  Biology DNA NOT cool | 1   1  | 

樣品結果:

item_id tag  title  tots 
    1  Biology DNA is cool 2 
    2  Medicine Doctors  1 
    3  Law Laws are cool 0 

2個問題:

  1. 我怎樣才能排除這些SELECT語句之一,如果它的結果​​將是NULL
  2. 是否有更好的方法來做到這一點查詢,而不是19個UNION ALL小號加入20條select語句?
+0

你沒有標籤的主表? –

+0

我可以但還沒有一個,我仍在考慮如何構建我的模式 –

+0

使用聚合函數SUM沒有GROUP BY隱式地在所有行上組;選擇'*'會導致檢索到不確定的記錄(有關更多信息,請參見[手冊](http://dev.mysql.com/doc/en/group-by-hidden-columns.html))... can你顯示樣品表數據和樣品所需的結果? – eggyal

回答

2

你只是想將你的結果—沒有什麼比這更復雜的(看不到UNION!):

SELECT items.*, SUM(purchaseyesno) AS tots 
FROM  items JOIN items_purchased USING (item_id) 
GROUP BY item_id 

UPDATE

下面的評論和更新OP的問題很明顯,問題比首先想到的更復雜:事實上,這是group-wise maximum問題的一個特例。

然而,在其上最大,必須採取該列是本身另一個組地聚集(的purchaseyesno求和)的結果。

因此,一個人的查詢變得相當不雅與子查詢:

SELECT * 
FROM (
    SELECT items.*, IFNULL(SUM(purchaseyesno),0) AS tots 
    FROM  items LEFT JOIN items_purchased ON folder_id = item_id 
    GROUP BY item_id 
) AS t NATURAL JOIN (
    SELECT tag, MAX(tots) AS tots 
    FROM (
    SELECT items.*, IFNULL(SUM(purchaseyesno),0) AS tots 
    FROM  items LEFT JOIN items_purchased ON folder_id = item_id 
    GROUP BY item_id 
) AS u 
    GROUP BY tag 
) AS v 
GROUP BY tag 

見它sqlfiddle

這裏發生的事情是,(使用outer join包括如Law記錄有在items_purchased表中沒有引用),我們採取購買的總和爲每個項目(物化表u),然後確定的最大數量購買具有相同標籤名稱的物品。

然後,我們將結果(物化表v)與第一個表(u,再次物化爲表t)一起標記爲購買標籤名稱和數量。

最後,我們再次將結果分組tag,以確保如果具有相同標籤的多個商品具有相同數量的最大購買數量,則只有其中一個不確定地返回。

+0

它不會是一個簡單的加入,因爲你也會得到item3 –

+0

@SashiKant:OP的所需結果集省略了'item_id = 3',所以我使用了內連接而不是外連接。這實現了所期望的。請參閱[sqlfiddle](http://sqlfiddle.com/#!2/92b5c/1)。 – eggyal

+0

@eggyal謝謝你的回答,我簡化了我的問題,以示範點。你能告訴我你的查詢將如何看它的項目表「item_id」實際上稱爲「folder_id」,但items_purchased仍稱爲「item_id」? –

0

創建一個主表的標籤,並保存它的ID會被用作名稱表。 然後下面的查詢將是你的問題的解決方案..

select *, sum(purchaseyesno) as tots 
from items left join 
items_purchased ip on (items.item_id=items_purchased.item_id) 
inner join tag_table on (tag_table.id=tagId) 
where deleted!=1 and pub_priv!=1 and not items.item_id is null group by tagID 
+0

- @ sashi謝謝!我正在生成示例表數據/結果,但會在接下來的幾分鐘內做到這一點.. –

+0

此查詢仍然返回不確定的結果,如[我上面的評論]中所述(http://stackoverflow.com/questions/11205424/select - 大多數觀看的項目按標籤名稱與MySQL的#comment14710700_11205424)。 – eggyal

+0

@eggyal:請檢查我的查詢是否正確,因爲我使用了 –