基于 TSQL / Microsoft SQL 服务器中另一个字段的字段的数据透视值
Pivot values of field based on another field in TSQL / Microsoft SQL Server
好的,这是 table 我有示例数据。 itemCode 和 dateType 有一个唯一的键,所以没有 itemCode 可以有重复的 dateType,反之亦然。 dateStatus 也是一种位数据类型。
+----+----------+----------+------------+-----------+--------------+
| id | itemCode | dateType | dateStatus | dateDue | dateComplete |
+----+----------+----------+------------+-----------+--------------+
| 1 | 501 | aa | 1 | 1/1/2014 | 5/1/2014 |
| 2 | 501 | bb | 0 | 1/2/2014 | |
| 3 | 501 | cc | 0 | 1/3/2014 | |
| 4 | 602 | aa | 0 | 1/4/2014 | |
| 5 | 602 | bb | 1 | 1/5/2014 | 5/5/2014 |
| 6 | 602 | cc | 0 | 1/6/2014 | |
| 7 | 602 | dd | 0 | 1/7/2014 | |
| 8 | 703 | bb | 0 | 1/8/2014 | |
| 9 | 703 | cc | 0 | 1/9/2014 | |
| 10 | 703 | dd | 1 | 1/10/2014 | 5/10/2014 |
+----+----------+----------+------------+-----------+--------------+
我正在尝试根据 itemCode 转换 dateType 并将值设置为 dateComplete 或 dateDue,具体取决于 dateStatus 是 0 还是 1。
+----------+---------------+---------------+---------------+----------------+
| itemCode | aa | bb | cc | dd |
+----------+---------------+---------------+---------------+----------------+
| 501 | fin: 5/1/2014 | due: 1/2/2014 | due: 1/3/2014 | |
| 602 | due: 1/4/2014 | fin: 5/5/2014 | due: 1/6/2014 | due: 1/7/2014 |
| 703 | | due: 1/8/2014 | due: 1/9/2014 | fin: 5/10/2014 |
+----------+---------------+---------------+---------------+----------------+
我可以在 Access Query CrossTab 中轻松完成此操作,SQL 结果为
TRANSFORM First(Switch([dateStatus]=0,"due: " & [dateDue],
[dateStatus]=1,"fin: " & [dateComplete])) AS Expr1
SELECT Table1.itemCode
FROM Table1
GROUP BY Table1.itemCode
PIVOT Table1.dateType In ("aa","bb","cc","dd");
但我不知道如何在 TSQL / Microsoft SQL 服务器管理工作室中构建此查询。我可以完成一些基本的数据透视,但聚合函数似乎无法提取值,所以我认为查询可能是数据透视、连接和案例语句的组合。或者也许我把事情复杂化了。
任何可供参考的代码都会非常有帮助。谢谢
一种选择是使用条件聚合来 pivot
您的结果,但您还必须使用 case
来选择正确的日期:
select itemcode,
max(case when dateType = 'aa' and dateStatus = 0
then 'due:' + cast(dateDue as varchar(20))
when dateType = 'aa' and dateStatus = 1
then 'fin:' + cast(dateComplete as varchar(20))
end) as aa,
max(case when dateType = 'bb' and dateStatus = 0
then 'due:' + cast(dateDue as varchar(20))
when dateType = 'bb' and dateStatus = 1
then 'fin:' + cast(dateComplete as varchar(20))
end) as bb,
max(case when dateType = 'cc' and dateStatus = 0
then 'due:' + cast(dateDue as varchar(20))
when dateType = 'cc' and dateStatus = 1
then 'fin:' + cast(dateComplete as varchar(20))
end) as cc,
max(case when dateType = 'dd' and dateStatus = 0
then 'due:' + cast(dateDue as varchar(20))
when dateType = 'dd' and dateStatus = 1
then 'fin:' + cast(dateComplete as varchar(20))
end) as dd
from Table1
group by itemCode
另一种选择是使用 pivot
命令,但您仍然需要在子查询中使用 case
语句来创建正确的日期值。
试试这个。它比接受的答案简单一点,而且可扩展性更强,比如添加了另一个 dateType。您所要做的就是在 pivot 中添加值,而不是一个全新的 case 语句。
DECLARE @pivotCols VARCHAR(MAX);
SELECT @pivotCols = COALESCE(@pivotCols + ',','') + QUOTENAME(dateType)
FROM @yourTable
GROUP BY dateType
EXEC
(
'SELECT *
FROM
(
SELECT itemCode,
CASE
WHEN dateStatus = 1
THEN ''fin: '' + CAST(dateComplete AS CHAR(10))
ELSE ''due: '' + CAST(dateDue AS CHAR(10))
END dateDue,
dateType
FROM @yourTable
) A
PIVOT
(
MAX(dateDue) FOR dateType IN (' + @pivotCols + ')
) pvt'
)
好的,这是 table 我有示例数据。 itemCode 和 dateType 有一个唯一的键,所以没有 itemCode 可以有重复的 dateType,反之亦然。 dateStatus 也是一种位数据类型。
+----+----------+----------+------------+-----------+--------------+
| id | itemCode | dateType | dateStatus | dateDue | dateComplete |
+----+----------+----------+------------+-----------+--------------+
| 1 | 501 | aa | 1 | 1/1/2014 | 5/1/2014 |
| 2 | 501 | bb | 0 | 1/2/2014 | |
| 3 | 501 | cc | 0 | 1/3/2014 | |
| 4 | 602 | aa | 0 | 1/4/2014 | |
| 5 | 602 | bb | 1 | 1/5/2014 | 5/5/2014 |
| 6 | 602 | cc | 0 | 1/6/2014 | |
| 7 | 602 | dd | 0 | 1/7/2014 | |
| 8 | 703 | bb | 0 | 1/8/2014 | |
| 9 | 703 | cc | 0 | 1/9/2014 | |
| 10 | 703 | dd | 1 | 1/10/2014 | 5/10/2014 |
+----+----------+----------+------------+-----------+--------------+
我正在尝试根据 itemCode 转换 dateType 并将值设置为 dateComplete 或 dateDue,具体取决于 dateStatus 是 0 还是 1。
+----------+---------------+---------------+---------------+----------------+
| itemCode | aa | bb | cc | dd |
+----------+---------------+---------------+---------------+----------------+
| 501 | fin: 5/1/2014 | due: 1/2/2014 | due: 1/3/2014 | |
| 602 | due: 1/4/2014 | fin: 5/5/2014 | due: 1/6/2014 | due: 1/7/2014 |
| 703 | | due: 1/8/2014 | due: 1/9/2014 | fin: 5/10/2014 |
+----------+---------------+---------------+---------------+----------------+
我可以在 Access Query CrossTab 中轻松完成此操作,SQL 结果为
TRANSFORM First(Switch([dateStatus]=0,"due: " & [dateDue],
[dateStatus]=1,"fin: " & [dateComplete])) AS Expr1
SELECT Table1.itemCode
FROM Table1
GROUP BY Table1.itemCode
PIVOT Table1.dateType In ("aa","bb","cc","dd");
但我不知道如何在 TSQL / Microsoft SQL 服务器管理工作室中构建此查询。我可以完成一些基本的数据透视,但聚合函数似乎无法提取值,所以我认为查询可能是数据透视、连接和案例语句的组合。或者也许我把事情复杂化了。
任何可供参考的代码都会非常有帮助。谢谢
一种选择是使用条件聚合来 pivot
您的结果,但您还必须使用 case
来选择正确的日期:
select itemcode,
max(case when dateType = 'aa' and dateStatus = 0
then 'due:' + cast(dateDue as varchar(20))
when dateType = 'aa' and dateStatus = 1
then 'fin:' + cast(dateComplete as varchar(20))
end) as aa,
max(case when dateType = 'bb' and dateStatus = 0
then 'due:' + cast(dateDue as varchar(20))
when dateType = 'bb' and dateStatus = 1
then 'fin:' + cast(dateComplete as varchar(20))
end) as bb,
max(case when dateType = 'cc' and dateStatus = 0
then 'due:' + cast(dateDue as varchar(20))
when dateType = 'cc' and dateStatus = 1
then 'fin:' + cast(dateComplete as varchar(20))
end) as cc,
max(case when dateType = 'dd' and dateStatus = 0
then 'due:' + cast(dateDue as varchar(20))
when dateType = 'dd' and dateStatus = 1
then 'fin:' + cast(dateComplete as varchar(20))
end) as dd
from Table1
group by itemCode
另一种选择是使用 pivot
命令,但您仍然需要在子查询中使用 case
语句来创建正确的日期值。
试试这个。它比接受的答案简单一点,而且可扩展性更强,比如添加了另一个 dateType。您所要做的就是在 pivot 中添加值,而不是一个全新的 case 语句。
DECLARE @pivotCols VARCHAR(MAX);
SELECT @pivotCols = COALESCE(@pivotCols + ',','') + QUOTENAME(dateType)
FROM @yourTable
GROUP BY dateType
EXEC
(
'SELECT *
FROM
(
SELECT itemCode,
CASE
WHEN dateStatus = 1
THEN ''fin: '' + CAST(dateComplete AS CHAR(10))
ELSE ''due: '' + CAST(dateDue AS CHAR(10))
END dateDue,
dateType
FROM @yourTable
) A
PIVOT
(
MAX(dateDue) FOR dateType IN (' + @pivotCols + ')
) pvt'
)