如何将表格从行平整到列

时间:2019-11-15 08:33:10

标签: sql merge pivot mariadb mariadb-10.2

我使用MariaDB 10.2.21 我没有在其他地方看到这种确切的情况,因此我请求协助。

我有一个History表,其中包含JIRA问题中任何字段的每次更改一个记录:

+----------+---------------+----------+-----------------+---------------------+
| IssueKey | OriginalValue | NewValue |      Field      |     ChangeDate      |
+----------+---------------+----------+-----------------+---------------------+
| HRSK-184 | (NULL)        |        2 | Risk Detection  | 2019-10-24 10:57:27 |
| HRSK-184 | (NULL)        |        2 | Risk Occurrence | 2019-10-24 10:57:27 |
| HRSK-184 | (NULL)        |        2 | Risk Severity   | 2019-10-24 10:57:27 |
| HRSK-184 | 2             |        4 | Risk Detection  | 2019-10-25 11:54:07 |
| HRSK-184 | 2             |        6 | Risk Detection  | 2019-10-25 11:54:07 |
| HRSK-184 | 2             |        3 | Risk Severity   | 2019-10-24 11:54:07 |
| HRSK-184 | 6             |        5 | Risk Detection  | 2019-10-26 09:11:01 |
+----------+---------------+----------+-----------------+---------------------+

每个记录都包含新旧值以及已更改的字段类型(“字段”),当然还包含该更改的相应时间戳。

我想查询时间点状态,从而为我提供“风险严重性,风险发生和风险检测”每个字段的最新值的组合

结果应该是这样的:

+----------+----------------+-------------------+------------------+----------------------+
| IssueKey | Risk Severity  |  Risk Occurrence  |  Risk Detection  |  ChangeDate          |
+----------+----------------+-------------------+------------------+----------------------+
| HRSK-184 | 3              |  2                |  5               |  2019-10-26 09:11:01 |
+----------+----------------+-------------------+------------------+----------------------+

有什么想法吗?我被困住了... 预先感谢您的努力!

2 个答案:

答案 0 :(得分:2)

您冷漠地使用了两个内联查询

select 
    IssueKey,
    (
        select t1.NewValue 
        from mytable t1 
        where t1.IssueKey = t.IssueKey and t1.Field = 'Risk Severity'
        order by ChangeDate desc limit 1
    ) `Risk Severity`,
    (
        select t1.NewValue 
        from mytable t1 
        where t1.IssueKey = t.IssueKey and t1.Field = 'Risk Occurrence'
        order by ChangeDate desc limit 1
    ) `Risk Occurrence`,
    (
        select t1.NewValue 
        from mytable t1 
        where t1.IssueKey = t.IssueKey and t1.Field = 'Risk Detection'
        order by ChangeDate desc limit 1
    ) `Risk Severity`,
    max(ChangeDate) ChangeDate
from mytable t
group by IssueKey

(IssueKey, Field, ChangeDate, NewValue)上有一个索引,这应该是一个有效的选择。

Demo on DB Fiddle

IssueKey | Risk Severity | Risk Occurrence | Risk Severity | ChangeDate     
:------- | ------------: | --------------: | ------------: | :------------------
HRSK-184 |             3 |               2 |             5 | 2019-10-26 09:11:01

答案 1 :(得分:1)

MariaDB 10.2引入了一些Window Functions用于分析查询。

其中之一是RANK() OVER (PARTITION BY ...ORDER BY...)函数。

首先,您可以应用它,然后绕过Conditional Aggregation

SELECT IssueKey,
       MAX(CASE WHEN Field = 'Risk Severity'   THEN NewValue END ) AS RiskSeverity,
       MAX(CASE WHEN Field = 'Risk Occurrence' THEN NewValue END ) AS RiskOccurrence,
       MAX(CASE WHEN Field = 'Risk Detection'  THEN NewValue END ) AS RiskDetection,
       MAX(ChangeDate) AS ChangeDate
  FROM
  (
   SELECT RANK() OVER (PARTITION BY IssueKey, Field ORDER BY ChangeDate Desc) rnk,
          t.*
     FROM mytable t 
  ) t
  WHERE rnk = 1
  GROUP BY IssueKey;

IssueKey | RiskSeverity  | RiskOccurrence  | RiskDetection  | ChangeDate     
-------- + --------------+-----------------+----------------+--------------------
HRSK-184 |             3 |               2 |              5 | 2019-10-26 09:11:01

Demo