【问题标题】:SQL: aggregate and condenseSQL:聚合和压缩
【发布时间】:2020-05-03 01:16:25
【问题描述】:

我可以做一些我不知道该怎么做的事情。我有一个简单的查询,需要汇总和压缩。这是基本脚本:

select t.serial, t.make, t.model, t.upgrade_date, t.software_version             
FROM table t
Order by t.serial

这些是经过软件升级(最多 3 次)的电子设备。当然,上面的脚本将为同一设备提供多行,但软件版本不同,而品牌和型号保持不变。我了解如何使用 max 将其聚合到一行,例如,显示最新的软件版本。但是,我需要的是聚合并有一个精简的列,显示设备所在的每个软件版本(按顺序)。

它可能看起来像这样:

+------------------------------------------+ 
| Serial | Make | Model | Version_history  |
+------------------------------------------+
| A        Terra  1       1.1, 1.9, 2.1    |
+------------------------------------------+

或者,如果设备处于该版本,则最好将每个 software_version 显示为带有“upgrade_date”的列标题。实际上,了解这两种方法会很有用。

这可能看起来像这样:

+------------------------------------------------------------------------+
| Serial   Make   Model   1.1           1.9           2.1            2.3 |
+------------------------------------------------------------------------+
| A        Terra  1       01-Jan-2019   17-Jun-2019   31-Dec-2019        |
+------------------------------------------------------------------------+

毫无疑问,这真的很简单,但我终其一生都无法弄清楚。

【问题讨论】:

  • 使用listagg()可以轻松实现第一个输出
  • 太棒了。那很简单。谢谢。

标签: sql oracle select sql-order-by


【解决方案1】:

使用LISTAGG:

select serial,
       make,
       model,
       LISTAGG( software_version, ',' ) WITHIN GROUP ( ORDER BY upgrade_date )
         AS Version_history,
       LISTAGG( upgrade_date, ',' ) WITHIN GROUP ( ORDER BY upgrade_date )
         AS Version_dates
FROM   table
GROUP BY serial, make, model
Order by serial

或者,如果设备处于该版本,则最好将每个 software_version 显示为带有“upgrade_date”的列标题。

如果您知道版本,那么您可以使用PIVOT

SELECT serial,
       make,
       model,
       "1.1",
       "1.9",
       "2.1",
       "2.3"
FROM   table
PIVOT ( MAX( upgrade_date ) FOR software_version IN (
  '1.1' AS "1.1",
  '1.9' AS "1.9",
  '2.1' AS "2.1",
  '2.3' AS "2.3"
) )

db<>fiddle

如果您不知道版本,那么这将是一个dynamic pivot,而不是一个简单的 SQL 查询。您将需要使用两阶段过程来首先生成动态 SQL 查询,然后使用 EXECUTE IMMEDIATE 运行查询。一般来说,您不应该使用动态数据透视,而是在您用于访问数据库的任何编程接口(Java、Python、C# 等)中将行转置为列。

【讨论】:

  • 非常感谢。这正是我想要的。目前只有 3 个软件版本,但长期来看会有很多。该解决方案目前有效,我将复习动态枢轴。
  • @Sid 不要在 Oracle 中使用动态数据透视表。只需使用SELECT serial, make, model, software_version, upgrade_date FROM table,然后将其转置到任何中间层软件(JSP、PHP、Python、C#、ColdFusion 等)中,即可将行转换为那里的列;如果你在那里而不是在 Oracle(它喜欢有一组定义明确的静态列)中实现和维护它可能会简单得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
  • 2017-11-14
  • 2023-03-18
  • 2020-08-19
  • 1970-01-01
相关资源
最近更新 更多