0

我有一个包含电话记录的数据库(我不是电话推销员,这是紧急呼叫数据)。每一行都是一个通话记录。一些列包含时间信息。每个呼叫还有一个优先级列。它看起来像这样:

  PRIORITY    TIMING1     TIMING2     TIMING3
  -----0----------22----------3-----------43 
  -----1----------42----------10----------12
  -----0----------12----------13----------6
  -----2----------23----------12----------37
  -----1----------12----------16----------23

我需要的输出基本上是每个时间的这一行,所有时间的总和按优先级分组为列。我提前知道了固定数量的时间安排和优先级。它看起来像这样:

------------Priority 0-------Priority 1-------Priority 2
  Timing1----123--------------332--------------233
  Timing2----265--------------241--------------302
  Timing3----387--------------192--------------201

是否可以在单个查询中执行此类操作?该查询还必须能够在资源相当有限的移动平台上运行,尽管运行时间并不是什么大问题。鉴于此表的大小和内存问题,我宁愿避免使用临时表。

4

4 回答 4

3

您可以为此使用UNPIVOT和:PIVOT

这是查询的静态版本 - 静态版本意味着您对值进行硬编码。

select *
from
(
  select *
  from
  (
    select priority, timing1, timing2, timing3
    from yourtable
  ) x
  unpivot
  (
    value
    for field in (timing1, timing2, timing3)
  ) u
) x1
pivot
(
  sum(value)
  for priority in ([0], [1], [2])
) p

SQL Fiddle with Demo

您也可以动态执行此操作:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX),
    @colsPivotName as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+ quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yourtable') and
               C.name LIKE 'timing%'
         for xml path('')), 1, 1, '')

select @colsPivot = 
    STUFF((SELECT distinct ',' + Quotename(priority)
             from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsPivotName = 
    STUFF((SELECT distinct ',' 
           + Quotename(priority) + ' as Priority' + cast(priority as varchar(1))
             from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'select col, '+ @colsPivotName +'
      from
      (
        select priority, val, col
        from 
        (
          select priority, ' + @colsUnpivot + '
          from yourtable
        ) x
        unpivot
        (
          val
          for col in ('+ @colsUnpivot +')
        ) u
      ) x1
      pivot
      (
        sum(val)
        for priority in ( '+ @colspivot + ')
      ) p'

exec(@query)

SQL Fiddle with Demo

编辑#1,您在评论中说您使用的是没有PIVOT功能的 SQLite。但是您仍然可以使用 aUNION ALL然后使用带有 a 的聚合函数来执行此操作CASE

select col,
  sum(case when priority = 0 then value end) as Priority0,
  sum(case when priority = 1 then value end) as Priority1,
  sum(case when priority = 2 then value end) as Priority2
from
(
  select priority, timing1 as value, 'timing1' as col
  from yourtable
  union all
  select priority, timing2 as value, 'timing2' as col
  from yourtable
  union all
  select priority, timing3 as value, 'timing3' as col
  from yourtable
) x
group by col

SQL Fiddle with Demo

于 2012-09-05T17:13:38.233 回答
1

如果您不介意翻转/反转表格,您可以试试这个:

SELECT PRIORITY, SUM(TIMING1), SUM(TIMING2), SUM(TIMING3)
  FROM tbl
 GROUP BY PRIORITY
 ORDER BY PRIORITY
于 2012-09-05T17:10:21.360 回答
0

使用 SQL Sum 和 Over 函数执行聚合求和,请参阅此链接:http ://www.sqlteam.com/article/sql-sever-2005-using-over-with-aggregate-functions

于 2012-09-05T17:07:58.200 回答
0

既然您说您知道固定数量的行和列,那么这里是简单的实现:

SELECT 'Timing1' AS Timing, SUM(IIF(PRIORITY = 0, TIMING1, 0)) AS [Priority 0],
    SUM(IIF(PRIORITY = 1, TIMING1, 0)) AS [Priority 1], 
    SUM(IIF(PRIORITY = 2, TIMING1, 0)) AS [Priority 2]
FROM CallRecords
UNION ALL
SELECT 'Timing2' AS Timing, SUM(IIF(PRIORITY = 0, TIMING2, 0)) AS [Priority 0], 
    SUM(IIF(PRIORITY = 1, TIMING2, 0)) AS [Priority 1], 
    SUM(IIF(PRIORITY = 2, TIMING2, 0)) AS [Priority 2]
FROM CallRecords
UNION ALL
SELECT 'Timing3' AS Timing, SUM(IIF(PRIORITY = 0, TIMING3, 0)) AS [Priority 0], 
    SUM(IIF(PRIORITY = 1, TIMING3, 0)) AS [Priority 1], 
    SUM(IIF(PRIORITY = 2, TIMING3, 0)) AS [Priority 2]
FROM CallRecords

尽管按照@n8wrl 的建议翻转表格,但它可能会更快,除非您绝对需要这种格式。

于 2012-09-05T17:11:39.297 回答