我有2个表:items
和items_purchased
。 tag
名称和其他描述性信息位于items
表格中,每个项目的购买次数保存在items_purchased
表格中。这些表在item_id上JOIN
。
到目前为止,这是我的查询:
(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个问题:
SELECT
的结果为NULL
,我该如何排除其中一个UNION ALL
语句?答案 0 :(得分:2)
您只想将结果分组 - 没有比这更复杂的了(看不到UNION
!):
SELECT items.*, SUM(purchaseyesno) AS tots
FROM items JOIN items_purchased USING (item_id)
GROUP BY item_id
<强>更新强>
根据下面的评论和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
对结果进行分组,以确保如果具有相同标记的多个项目具有相同数量的最大购买量,则只会不确定地返回其中一个。
答案 1 :(得分: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