我有这样的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
有什么想法吗?
答案 0 :(得分:1)
因为你最近的问题与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。
我假设你可以将row_number添加到你的View中,这是一个接近的例子:
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;
祝你好运。
答案 1 :(得分:1)
Mark的问题答案会有所帮助。
这是哪个RDBMS - MySQL,Oracle,SQLServer ......?还有,你有没有 每个id需要三个以上的date_from,date_to对吗?
使用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