【问题标题】:SQL Server : pivot or not to pivotSQL Server:透视或不透视
【发布时间】:2023-04-08 02:17:01
【问题描述】:

我有一个表,我在其中运行一个 select 语句并返回以下数据

Name    date           skill    seconds  calls
----------------------------------------------
bob     9/2/2016       706      12771    56
bob     9/2/2016       707      4061     16
bob     9/2/2016       708      2577     15
bob     9/2/2016       709      2156     6

我想返回如下一行数据:

Name date     706sec   706call  707sec  707call  708sec  708call 709sec  709call
----------------------------------------------------------------------------------
bob  9/2/2016 12771     56       4061     16      2577     15     2156     6

我的第一次尝试是枢轴,但没有返回单行:

Select 
    name, date, seconds, calls, [706], [707],[708],[709],  
from 
    (Select 
         name, date, skill, seconds, calls
     From
         tablecalls 
     Where 
         date between '09/02/2016 00:00' and '09/02/2016 23:59' 
         and name = 'bob') as b
pivot 
    (sum(seconds) for skill in ([706], [707], [708], [709] )) as p1

这会返回:

name    date      calls 706sec  707sec  708sec  709sec
---------------------------------------------------------
bob     9/2/2016    6   NULL    NULL    NULL    2156
bob     9/2/2016   15   NULL    NULL    2577    NULL
bob     9/2/2016   16   NULL    4061    NULL    NULL
bob     9/2/2016   56   12771   NULL    NULL    NULL

也许PIVOT 不是这样做的正确方法。还有其他方法吗?

【问题讨论】:

  • 好吧,您可以使用 pivot,但它最终可能会比仅使用条件聚合效率低。例如select name, date, max(case when skill = 706 then seconds end) [706sec], max(case when skill = 706 then calls end) [706call], max(case when skill = 707 then seconds end) [707sec]... from mytable group by name, date.
  • 我试过 ZLK 的建议很有效。

标签: sql-server select pivot


【解决方案1】:

您能否格式化您有问题的数据。我不确定我是否明白你的意思?

    CREATE TABLE #tt([name] VARCHAR(10),[date] DATE,skill INT,seconds INT, calls int )
    INSERT INTO #tt
    SELECT 'bob','9/2/2016',706,12771,56 UNION all
    SELECT 'bob','9/2/2016',707,4061,16  UNION all
    SELECT 'bob','9/2/2016',708,2577,15  UNION all
    SELECT 'bob','9/2/2016',709,2156,6 

    SELECT * FROM (
        SELECT t.name,t.date,c.* FROM #tt AS t
        CROSS APPLY(VALUES(LTRIM(t.skill)+'sec',t.seconds),(LTRIM(t.skill)+'calls',t.seconds)) c(t,v)
    ) AS A
    PIVOT(MAX(v) FOR t IN ([706sec],[706calls],[707sec],[707calls],[708sec],[708calls],[709sec],[709calls])) p
姓名 日期 706sec 706calls 707sec 707calls 708sec 708calls 709sec 709calls ---------- ---------- ----------- ----------- -------- --- ----------- ------------ ----------- ----------- --- -------- 鲍勃 2016-09-02 12771 12771 4061 4061 2577 2577 2156 2156

如果技能计数不固定,可以使用动态脚本:

    DECLARE @col VARCHAR(max),@sql VARCHAR(max)
    SELECT @col=ISNULL(@col+',[','[')+LTRIM(skill)+'sec],['+LTRIM(skill)+'calls]' FROM #tt GROUP BY skill
    SET @sql='
    SELECT * FROM (
        SELECT t.name,t.date,c.* FROM #tt AS t
        CROSS APPLY(VALUES(LTRIM(t.skill)+''sec'',t.seconds),(LTRIM(t.skill)+''calls'',t.seconds)) c(t,v)
    ) AS A
    PIVOT(MAX(v) FOR t IN ('+@col+')) p'
    EXEC (@sql)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    相关资源
    最近更新 更多