sql行到列透视表

sql行到列透视表,sql,select,pivot,teradata,Sql,Select,Pivot,Teradata,我有如下sql视图: id date_from date_to 1 2005-01-05 2005-05-10 1 2005-01-05 2005-05-10 1 2005-01-05 2005-05-10 2 2005-01-01 2006-08-31 2 2010-01-01 2010-06-30 3 2005-01-01 2005-06-30 我想编写sql语句,返回: 1 2005-01-05 2005-05-10 2005-01-05 2005-05-10 2005-0

我有如下sql视图:

id date_from  date_to
1  2005-01-05 2005-05-10
1  2005-01-05 2005-05-10
1  2005-01-05 2005-05-10
2  2005-01-01 2006-08-31
2  2010-01-01 2010-06-30
3  2005-01-01 2005-06-30
我想编写sql语句,返回:

1 2005-01-05 2005-05-10 2005-01-05 2005-05-10 2005-01-05 2005-05-10
2 2005-01-01 2006-08-31 2010-01-01 2010-06-30 NULL       NULL
3 2005-01-01 2005-06-30 NULL       NULL       NULL       NULL

有什么想法吗?

因为你最近提出的问题都与MySQL有关,所以我假设你想要一个MySQL解决方案

如果您知道潜在日期范围的最大数量,则可以使用max和CASE。但是,您必须有一个行计数器,因为您没有任何其他唯一标识符(实际上我建议将其添加到视图中,因为您提到这是一个视图)。但这里是:

SELECT Id,
   MAX(CASE WHEN row_number = 1 THEN date_from END) date_from1,
   MAX(CASE WHEN row_number = 1 THEN date_to END) date_to1,
   MAX(CASE WHEN row_number = 2 THEN date_from END) date_from2,
   MAX(CASE WHEN row_number = 2 THEN date_to END) date_to2,
   MAX(CASE WHEN row_number = 3 THEN date_from END) date_from3,
   MAX(CASE WHEN row_number = 3 THEN date_to END) date_to3
FROM (
  SELECT 
      id, 
      @running:=if(@previous=id,@running,0) + 1 as row_number,
      @previous:=id,
      date_from, date_to
  FROM YourView 
      JOIN    (SELECT @previous := 0) r
    ORDER BY id, date_from, date_to
) t
GROUP BY Id
如果您不知道日期范围的最大数目,那么您将无法使用一条SQL语句来实现这一点。相反,您需要使用动态SQL

我假设您可以将行号添加到视图中,下面是一个示例:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(CASE WHEN row_number = ', 
      row_number, 
      ' THEN date_from END) date_from', 
      row_number)
  ),
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(CASE WHEN row_number = ',  
      row_number, 
      ' THEN date_to END) date_to',  
      row_number)
  ) INTO @sql
FROM YourView;

SET @sql = CONCAT('SELECT  ID, ', 
                   @sql, ' 
                   FROM    YourView
                   GROUP   BY ID');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

祝你好运。

回答马克的问题会有所帮助


这是哪种关系数据库管理系统-MySQL、Oracle、SQLServer。。。?还有,你有过吗 每个id需要三对以上的日期对吗

使用t-sql,我显式地处理3个级别。如果希望它是动态的,则需要动态创建查询

DECLARE @staging TABLE
(
    id int NOT NULL,
    date_from datetime NOT NULL,
    date_to datetime NOT NULL,
    step int
)

INSERT INTO @staging
SELECT id, date_from, date_to,
    ROW_NUMBER() OVER(PARTITION BY id ORDER BY date_from, date_to)
FROM tblTemp

-- below is static for 3 levels, make below dynamic to match what you want
SELECT t1.id, t1.date_from, t1.date_to, t2.date_from, t2.date_to, t3.date_from, t3.date_to
FROM @staging t1 LEFT OUTER JOIN
    @staging t2 ON t1.id = t2.id AND t2.step = 2 LEFT OUTER JOIN
    @staging t3 ON t2.id = t3.id AND t3.step = 3
WHERE t1.step = 1

测试@

这是哪种RDBMS-MySQL、Oracle、SQLServer。。。?此外,你是否会希望每个id有三对以上的日期从、日期到配对?从你在标题和标签中加入“轴心”这一事实来看,你显然已经有了一个想法,但显然它不起作用。怎么了?还有,您使用的是什么数据库管理系统?我使用的是Teradata。视图可以有3个以上的日期在相同的情况下,但我想使用3个最新的日期。谢谢,它看起来很棒。我明天会在Teradata上试用。@PetrNovák,我是Teradata的新手。我刚刚证实,几乎所有上述内容都将起作用。唯一有问题的部分是临时表。您可以将临时表声明为Teradata中的易失性表,该表将在用户的假脱机空间中创建。