【问题标题】:SQL Server TransposeSQL Server 转置
【发布时间】:2016-07-29 03:33:54
【问题描述】:

我想转置Select,但无法理解Pivot,我对许多教程中的以下内容更加困惑:

“如果源数据被正确规范化,就不需要转换列和行。如果您发现自己需要定期执行这种类型的转换,那么您的架构设计就有问题”。

具体而言,规范化如何使 Select 返回以下转置后的值:

SELECT 
    Date, Activity 
FROM 
    EVENTS 
WHERE 
    CITY = 'Seattle' 

(即不是事件日期在第 1 列中下降,我希望将日期作为列进行)

【问题讨论】:

  • 有多少个日期,数量会有所不同吗?这个问题的答案将决定您是否需要动态 SQL 来解决您的问题。
  • 我猜引用的语句更多地是指非透视而不是透视。例如您可以使用“Seattle”、“SomeOtherCity”、“SomeOtherOtherCity”或类似的栏目来代替城市栏。规范化你的数据可以更容易地使用 PIVOT,因为你不必规范化它(UNPIVOT)然后 PIVOT,我猜。如果没有 PIVOT 语句,它不会完全启用 PIVOT。

标签: sql-server transpose database-normalization


【解决方案1】:

也许您可以选择类似于以下示例的方法, 我将 dynamic SQL 与 CTE 语句和 CASE 运算符一起使用。 我只是使用 CTE 表达式将 datetime 转换为 date 数据类型,而不是在每个 CASE 语句中重复转换

declare @mm varchar(2) = datepart(mm,getdate())
declare @sql nvarchar(max)
set @sql = N'
;with cte as (
    SELECT 
        DATEPART(dd,[date]) dd,
        convert(date,[date]) [date],
        Activity
    FROM 
        [events]
)
SELECT
    case when dd = 1 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 2 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 3 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 17 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 18 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 19 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 20 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 28 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 29 then Activity end as ''' + '01/'+@mm+'/2016' + ''',
    case when dd = 30 then Activity end as ''' + '01/'+@mm+'/2016' + '''
FROM cte'
print @sql
exec sp_executeSQL @sql

当然dynamic pivot query 会更好地满足您的要求。 您可以从静态数据透视示例开始了解结构,然后处理您的示例案例。在最后一步,您可以将代码转换为动态数据透视查询

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多