【问题标题】:MySQL GROUP BY selected column emptyMySQL GROUP BY 选定列为空
【发布时间】:2015-06-28 20:55:30
【问题描述】:

我有一个包含多条记录的数据库,我想在其中进行分组。例如:

cat_id | p_id | amount | sold | date       | title
---------------------------------------------
1      | 1    | 4      | 3    | 2015-04-21 | title of product 1
1      | 1    | 0      | 5    | 2015-04-03 | 
2      | 1    | 3      | 1    | 2015-04-21 | title of product 2
2      | 1    | 0      | 3    | 2015-04-05 | 

在此表中,有两个唯一产品,即 cat_id 1 中的 p_id 1 和 cat_id 2 中的 p_id 1。现在我想获取所有产品的所有列表,将其 amountsold 相加。标题仅在金额 > 0 时填写。 所以我写了这个查询:

SELECT SUM (amount), SUM(sold) cat_id, p_id, title
FROM table
GROUP BY cat_id, p_id

这会返回我:

cat_id | p_id | amount | sold | title
---------------------------------------------
1      | 1    | 4      | 8    |
2      | 1    | 3      | 4    |

所以现在我错过了我的头衔。 我尝试了一些链接GROUP_CONCAT(DISTINCT title),但它连接在一起,这不是我真正想要的。我只需要标题。

我将如何解决这个问题。

注意:更新的问题

【问题讨论】:

  • 是否会出现相同 cat_id 和 p_id 的产品标题不同的情况?如果这种情况永远不会发生,那么如果您只关心数量 > 0,为什么还需要分组?
  • 我更新了我的问题,问题不完整!还有一列sold 需要求和。即使amount == 0.

标签: mysql


【解决方案1】:

在标题周围添加 MAX() 将强制它选择 NOT NULL 值

SELECT SUM (amount), SUM(sold) cat_id, p_id, MAX(title)
FROM table
WHERE amount > 0
GROUP BY cat_id, p_id

【讨论】:

  • MAX() 正在做这项工作!太好了!
【解决方案2】:

试试:

SELECT SUM (amount), SUM(sold), cat_id, p_id, title
FROM table
GROUP BY cat_id

更新 SQLFiddle :http://sqlfiddle.com/#!9/a5ca3/3

【讨论】:

  • 当表中的第一条记录没有titel,但第二行有title时,您的解决方案不起作用。
【解决方案3】:

此处标题的根本问题是,如果您使用 GROUP BY 而不使用聚合函数,则返回的值是不确定的(请参阅 this question)。

因此,最好的办法是以某种方式解决这个问题——一个明显的解决方案是为每一行填写 title,而不仅仅是数量 > 0 的地方(或者甚至更好,规范化您的数据!)。但是,如果您不能这样做,您可以在 GROUP_CONCAT 中使用您的标题中不存在的分隔符(例如,'||||'),并且由于 GROUP_CONCAT 返回一个文本字段,您可以使用REPLACE 摆脱它:

SELECT SUM (amount), SUM(sold) cat_id, p_id, REPLACE(GROUP_CONCAT(DISTINCT title ORDER BY title DESC SEPARATOR '||||'), '||||', '') AS title
FROM table
GROUP BY cat_id, p_id

我做了一个简化的 SQL Fiddle here,也许你可以用它来做你想做的事。

【讨论】:

  • 我没有用标题填写每一行,因为它是多余的信息,这样可以节省空间。您的解决方案运行良好,但 MAX() 功能也运行良好且容易得多。
【解决方案4】:

您将希望在标题上使用 MAX(),以便它提取非空白或 null 的标题。虽然你的桌子是这样设计的,但这似乎有点奇怪......

SELECT SUM(amount), SUM(sold) cat_id, p_id, MAX(title) AS `Title`
FROM table
GROUP BY cat_id, p_id

【讨论】:

  • MAX() 确实有效。我将标题从其他记录中删除以节省空间,因为它是冗余信息。这张桌子确实设计得有点奇怪。那是因为它从来都不是为做我现在所做的事情而设计的。认为我必须考虑重新设计桌子。
  • @Timo002 如果您想节省多次存储标题的空间,您可能应该考虑使用标题查找表。
猜你喜欢
  • 2011-01-12
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 2018-06-16
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多