mysql - 使用 mysql 按标签名称选择查看次数最多的项目

标签 mysql select union

我有 2 个表:itemsitems_purchasedtag 名称和其他描述性信息位于 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 个问题:

  1. 如果其中一个 SELECT 语句的结果为 NULL,如何排除该语句?
  2. 是否有比 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/

相关文章:

mysql - 当 Key_name 与 Column_name 不匹配时,删除外键不起作用

php - 如何实现字符串值到日期格式

sqlite - 使用 Persist 将 Sqlite 表中所有记录中的一列提取到 Haskell 中的串联字符串中

hadoop - HiveQL 联合所有

sql - 将具有两列的行转换为一列的两行

php - 创建一个表单以使用 MySQL 更新 JSON 数据

Java MySql PoolableConnectionFactory &

MySQL - 如何在 SELECT 查询中使用 ENCLOSED BY?

PHP 和 SQL - 如何选择当年所有月份的最高总和?

MySQL UNION - 检测几个 SELECT 的返回结果