如何编辑这个 mySQL 以便将相同 id 的行组合成 1 而不是 3?

Posted

技术标签:

【中文标题】如何编辑这个 mySQL 以便将相同 id 的行组合成 1 而不是 3?【英文标题】:How to edit this mySQL so as to combine the rows of the same id into 1 instead of 3? 【发布时间】:2016-08-09 10:53:12 【问题描述】:

以下 mysql 查询从 alerts_dataalerts_list 两个表中获取数据。第一个表包含警报的数据,第二个表包含警报的描述。所以在alerts_data 中有多行具有相同的alerts_data_id 与alerts_list 的alerts_id 相同。

我想要实现的是显示这样的东西

alert number 51, 5 clicked , 2 closed
alert number 57, 13 clicked, 3 closed, 8 waiting

使用 mySQL 或 php(我不知道我是否可以通过普通的 mySQL 得到这个)

所以目前据我所知,我无法在一行中显示警报 51 的数据,但由于 alerts_data_status 不同,我必须为每个显示 3 行。

我该怎么做?

SELECT COUNT( alerts_data_id ) AS total, alerts_data_id, alerts_data_status, alerts_list.alerts_title
FROM  alerts_data 
JOIN alerts_list ON 
alerts_data.alerts_data_id = alerts_list.alerts_id
GROUP BY alerts_data_id, alerts_data_status

//输出

total - alerts_data_id - alerts_data_status - alerts_title
5     -     51 - clicked - alert number 51
2     -     52 - closed - alert number 51
13    -     57 - clicked - alert number 57
3     -     57 - waiting - alert number 57
8     -     57 waiting - alert number 57

注意:警报编号只是示例,可以是任意编号

// 警报数据

id - alerts_data_id - alerts_data_status

// alerts_list

alerts_id - alerts_name - alerts_text

这是一个 sqlfiddle:http://sqlfiddle.com/#!9/c70c2/1

【问题讨论】:

你能分享示例 sql 转储吗?如果没有,您可以同时使用多个选择,例如; select count(),(select count() from alert_list al where al.alert_data_id=ad.id) @merdincz 嗨,我上面添加的输出是实际输出。 @merdincz 我现在包含了两个表的结构。谢谢 【参考方案1】:

这可能是GROUP_CONCAT()的申请。

您首先需要按 alerts_data_id 和 alerts_data_status 的警报摘要。这有点复杂,因为您的 sqlfiddle 有一大堆空的 alerts_data_status 字符串。在这里,我将那些空字符串替换为“?”。 (http://sqlfiddle.com/#!9/c70c2/23/0)

                      SELECT COUNT(*) AS alerts_count, 
                             alerts_data_id, 
                             CASE WHEN LENGTH(alerts_data_status) = 0 THEN '?'
                                  ELSE alerts_data_status END  AS alerts_data_status
                        FROM alerts_data
                       GROUP BY alerts_data_id, alerts_data_status

然后你想在另一个查询中汇总它

SELECT SUM(a.alerts_count) total,
       a.alerts_data_id, b. alerts_name,
       GROUP_CONCAT( CONCAT(a.alerts_count, ': ', a.alerts_data_status)
                     ORDER BY a.alerts_data_status
                     SEPARATOR "; " ) detail
  FROM (
                      SELECT COUNT(*) AS alerts_count, 
                             alerts_data_id, 
                             CASE WHEN LENGTH(alerts_data_status) = 0 THEN '?'
                                  ELSE alerts_data_status END  AS alerts_data_status
                        FROM alerts_data
                       GROUP BY alerts_data_id, alerts_data_status
       ) a
  JOIN alerts_list b ON a.alerts_data_id = b.alerts_id
 GROUP BY a.alerts_data_id, b.alerts_name

这将为每个不同的 alerts_data_id 提供一行。每个警报都由它的计数、它的 id 和它的名称来标识。 (http://sqlfiddle.com/#!9/c70c2/26/0)

然后该行将包含一个以分号分隔的不同警报状态的计数列表。

【讨论】:

嗨,这真是太棒了,谢谢!我将您的代码编辑到此sqlfiddle.com/#!9/c7d832/11,以便没有空白,而是处于等待状态。我的问题是我可以为每个状态设置一列而不是一列吗? 行成列的操作的行话叫做pivoting表。在 MySQL 中,这是一个臭名昭著的痛苦。 siax 的答案是正确的方法。【参考方案2】:

如果我很了解你,我认为这就是你所需要的;

SELECT 
  COUNT( alerts_data.id ) AS total, 
  ad.id,
  (SELECT count(*) from alert_list al where al.alerts_id=ad.id and alerts_data_status='clicked') as clicked,
  (SELECT count(*) from alert_list al where al.alerts_id=ad.id and alerts_data_status='closed') as closed,
  (SELECT count(*) from alert_list al where al.alerts_id=ad.id and alerts_data_status='waiting') as waiting,
FROM  alerts_data ad
GROUP BY ad.id

【讨论】:

谢谢,不过我遇到了很多错误。我正在尝试修复它们以通过 phpmyadmin 如果您可以与示例数据共享您的表。我想我可以给你正确的查询。 嘿,再次,请在这里找到架构和所有内容sqlfiddle.com/#!9/c70c2/1 我不确定输出列的准确度,但我来宾 sqlfiddle.com/#!9/c70c2/11 对您来说没问题,或者您可以更改列和文本字段。 你能给我更多关于你的输出的细节吗?您需要“警报编号 51、5 单击 5、2 关闭 2”的输出我的客人警报编号 51 部分还可以,不是吗?那么点击之前的 5 是什么意思呢?【参考方案3】:

正在检查其他答案和您的 SQLFIDDLE,并认为这可能是一个更好的方法:

SELECT alerts_list.alerts_title,
  SUM(CASE WHEN alerts_data_status = 'clicked' THEN 1 ELSE 0 END) AS clicked,
  SUM(CASE WHEN alerts_data_status = 'closed' THEN 1 ELSE 0 END) AS closed,
  SUM(CASE WHEN alerts_data_status = 'waiting' THEN 1 ELSE 0 END) AS waiting
FROM alerts_data 
JOIN alerts_list ON alerts_data.alerts_data_id = alerts_list.alerts_id
GROUP BY alerts_list.alerts_title

【讨论】:

那么这是怎么回事?我的回答是认真地帮助你。

以上是关于如何编辑这个 mySQL 以便将相同 id 的行组合成 1 而不是 3?的主要内容,如果未能解决你的问题,请参考以下文章

查找具有已定义结束的连续相同值的行组 (SQL Redshift)

如何在pandas中将多个相同类别的行组合成一个?

使用 php 编辑文本文件中的行组

如何使用熊猫将多行组合成具有多条件的行[关闭]

Oracle SQL - 过滤掉包含具有特定值的行的分区或行组

将 id 插入具有相同信息的行的 PL/SQL 过程