mysql - MySQL 中的动态透视 - 如何从 mySQL 存储过程中的 select 循环进入字段?

标签 mysql stored-procedures

也许是一个业余问题,但现在我还没有提出解决方案,也许有人知道我的想法是错误的。

我的计划是,调用 mySQL 存储过程。这个过程应该返回我类似的东西:

+---------------+---------------+---------------+---------------+---------------+
| Date          | 100           | 101           | 102           | 103           |
+---------------+---------------+---------------+---------------+---------------+
| 2019-10-21    | 1             | 2             | 3             | 4             |
| 2019-10-20    | 0             | 2             | 3             | 4             |
| 2019-10-19    | 0             | 2             | 3             | 4             |
| 2019-10-18    | 1             | 2             | 3             | 4             |
| 2019-...      | ..            | ..            | ..            | ..            |
+---------------+---------------+---------------+---------------+---------------+

“主要数据”存储在“logging”表中,该表包含 id、code、created_at 列。第二个表“codes”包含所有可用代码的列表,其中包含列 id(<- 日志中的代码)和说明。

现在,我的第一步是,构建一个存储过程来处理最小日期和最大日期之间的所有日期。看起来像这样:

BEGIN
set @dateStart := (SELECT MIN(created_at) FROM loggings);
set @dateEnd := (SELECT MAX(created_at) FROM loggings);
set @d := 0;
SELECT DATE(ADDDATE(@dateStart, INTERVAL @d:=@d+1 DAY)) AS date,
IFNULL((
    SELECT COUNT(*) FROM loggings AS m2
    WHERE DATE(m2.created_at) = DATE(ADDDATE(@dateStart, INTERVAL @d DAY))
),0) AS total
FROM loggings AS m1
HAVING @d < DATEDIFF(@dateEnd, @dateStart);
END

工作正常,我得到一个结果列表,其中包含所有日期和每天的记录总数:

+---------------+---------------+
| date          | total         |
+---------------+---------------+
| 2019-10-21    | 1             |
| 2019-10-20    | 2             |
| 2019-10-19    | 3             |
| 2019-10-18    | 4             |
| 2019-...      | ..            |
+---------------+---------------+

现在,接下来,我目前不太了解如何解决它的部分:如何将“代码”的可用 id 循环到结果的一组列中? 不知何故,我必须在选择返回动态字段的内部/外部构建一个循环,但是如何构建?

编辑: 日志记录的示例数据可以是:

+----------+----------+----------+----------------------+
| id       | email    | code     | created_at           |
+----------+----------+----------+----------------------+
| 1        | a@y.de   | 100      | 2019-10-21 10:00:01  |
| 2        | b@y.de   | 100      | 2019-10-21 10:00:02  |
| 3        | c@y.de   | 101      | 2019-10-21 10:01:03  |
| 4        | d@y.de   | 102      | 2019-10-21 11:01:03  |
| 5        | a@y.de   | 100      | 2019-10-21 12:01:03  |
| 6        | b@y.de   | 103      | 2019-10-21 15:01:03  |
| 7        | e@y.de   | 106      | 2019-10-21 15:01:04  |
| 8        | f@y.de   | 108      | 2019-10-21 16:01:03  |
| 9        | g@y.de   | 109      | 2019-10-21 17:01:03  |
+----------+----------+----------+----------------------+

该表通过代码记录不同的事件,并使用创建时间戳和电子邮件作为识别用户的关键,触发“事件”。

最佳答案

您想要实现的最终结果称为 Dynamic pivot 。您可以尝试以下查询来达到您想要的结果 -

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'count(case when code = ',
      code,
      ' then created_at else null end) AS ''',
      code, ''''
    )
  ) INTO @sql
FROM LOGGINGS;

SET @sql = CONCAT('SELECT date(created_at), ', @sql, '
                   FROM LOGGINGS 
                   GROUP BY date(created_at)');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Here是 fiddle 。

关于mysql - MySQL 中的动态透视 - 如何从 mySQL 存储过程中的 select 循环进入字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58482110/

相关文章:

asp.net - 将 List<string> 传递给存储过程

mysql 交叉表错误总和

mysql - MariaDB 不在 Ubuntu 15.04 上检查密码

mysql - 在 MySQL 中搜索日期范围最有效的方法是什么?

mysql - 属性 'mongoOperations' 抛出 NoSuchMethodException

sql - 从 2 个组合返回一个表的存储过程

javascript - Ajax 和 MySql 插入、检查和检索

mysql - 有条件更新/插入 - 'END' 附近的语法不正确

php - 使用存储过程列出记录

C# ASP.Net Parameters.AddWithValue 拒绝参数的空值