我有 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
问题是尚未购买带有某些标签的商品,因此查询会抛出列“item_id”不能为空
错误。
这是示例表:
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
,如何排除该语句? - 是否有比 20 个 select 语句(由 19 个
UNION ALL
连接)更好的方法来执行此查询?
最佳答案
您只是想对结果进行分组 - 没有比这更复杂的了(看不到 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 包含在 items_purchased
表中没有引用的 Law
等记录),我们计算购买总和对于每个商品(物化表u
),然后确定具有相同标签名称的商品的最大购买数量。
然后,我们将结果(具体化表 v
)与第一个表(u
,再次具体化为表 t
)连接起来标签名称和购买数量。
最后,我们再次按标签
对结果进行分组,以确保如果具有相同标签的多个商品具有相同的最大购买次数,则只会不确定地返回其中一个。
关于mysql - 使用 mysql 按标签名称选择查看次数最多的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11205424/