我正在尝试查询表格以进行数据转换,但我遇到了结构问题。我猜我需要转动然后是Unpivot,但我不知道从哪里开始。
这是我目前的表格
+----+-----------+-------+---------+
| ID | field | value | date |
+----+-----------+-------+---------+
| 1 | Draw1 | 1500 | NULL |
| 1 | Draw1Date | NULL | 4/15/16 |
| 1 | Draw1Fee | 100 | NULL |
| 1 | Draw2 | 2000 | NULL |
| 1 | Draw2Date | NULL | 3/14/17 |
| 1 | Draw2Fee | 100 | NULL |
| 2 | Draw1 | 800 | NULL |
| 2 | Draw1Date | NULL | 4/16/18 |
| 2 | Draw1Fee | 150 | NULL |
| 2 | Draw2 | 760 | NULL |
| 2 | Draw2Date | NULL | 5/6/18 |
| 2 | Draw2Fee | 150 | NULL |
+----+-----------+-------+---------+
需要的结果
+----+-------+---------+---------+------+
| ID | Draws | Amount | Date | Fee |
+----+-------+---------+---------+------+
| 1 | Draw1 | 1500 | 4/15/16 | 100 |
| 1 | Draw2 | 2000 | 3/14/17 | 100 |
| 2 | Draw1 | 800 | 4/16/18 | 150 |
| 2 | Draw2 | 760 | 5/6/18 | 150 |
+----+-------+---------+---------+------+
答案 0 :(得分:2)
我的回答适用于提供的数据。如果您正在寻找更通用的解决方案,对于更多种类的数据,您可能会尝试找到另一个答案。我没有使用PIVOT / UNPIVOT。
测试数据:
create table #t (ID int, field varchar(20), [value] int, [date] date)
insert into #t values
(1 ,'Draw1' , 1500 , NULL ),
(1 ,'Draw1Date' , NULL , '4/15/16'),
(1 ,'Draw1Fee' , 100 , NULL ),
(1 ,'Draw2' , 2000 , NULL ),
(1 ,'Draw2Date' , NULL , '3/14/17'),
(1 ,'Draw2Fee' , 100 , NULL ),
(2 ,'Draw1' , 800 , NULL ),
(2 ,'Draw1Date' , NULL , '4/16/18'),
(2 ,'Draw1Fee' , 150 , NULL ),
(2 ,'Draw2' , 760 , NULL ),
(2 ,'Draw2Date' , NULL , '5/6/18' ),
(2 ,'Draw2Fee' , 150 , NULL )
<强>查询:强>
;with ct as (
select ID, field
from #t
where field in ('Draw1', 'Draw2')
group by ID, field
)
select ct.ID, ct.field
, t1.[value] as Amount, t2.[date] as [Date], t3.[value] as Fee
from ct
inner join #t t1 on t1.ID = ct.ID and t1.field = ct.field
inner join #t t2 on t2.ID = ct.ID and t2.field = ct.field + 'Date'
inner join #t t3 on t3.ID = ct.ID and t3.field = ct.field + 'Fee'
<强>结果:强>
ID field Amount Date Fee
1 Draw1 1500 2016-04-15 100
1 Draw2 2000 2017-03-14 100
2 Draw1 800 2018-04-16 150
2 Draw2 760 2018-05-06 150
答案 1 :(得分:1)
我会这样做:
select id, left(field, 5),
max(case when len(field) = 5 then value end) as value,
max(case when field like '%date' then value end) as date,
sum(case when field like '%fee' then value end) as fee
from t
group by id, left(field, 5);
如果您的字段确实更复杂,那么您最近是否在寻找date
和fee
之前的任何内容,然后使用cross apply
:
select t.id, v.draws,
max(case when t.field = v.draws then value end) as value,
max(case when t.field like '%date' then value end) as date,
sum(case when t.field like '%fee' then value end) as fee
from t cross apply
(values (replace(replace(field, 'date', ''), 'fee', '')) v(draws)
group by id, v.draws;
答案 2 :(得分:1)
试试这个......
SELECT tblAmount.id AS ID,
tblAmount.field AS Draws,
Max(tblAmount.value) AS Amount,
Max(tblDate.[date]) AS [Date],
Max(tblFee.value) AS Fee
FROM tablename tblAmount
INNER JOIN (SELECT id, field, [date]
FROM tablename
WHERE [date] IS NOT NULL AND field LIKE '%Date') tblDate
ON tblAmount.id = tblDate.id
AND tblDate.field LIKE tblAmount.field + '%'
INNER JOIN (SELECT id, field, value
FROM tablename
WHERE value IS NOT NULL AND field LIKE '%Fee') tblFee
ON tblAmount.id = tblFee.id
WHERE tblAmount.value IS NOT NULL
AND tblAmount.field NOT LIKE '%Fee'
AND tblAmount.field NOT LIKE '%Date'
GROUP BY tblAmount.id, tblAmount.field
ORDER BY tblAmount.id, tblAmount.field
输出
+----+-------+--------+------------+-----+
| ID | Draws | Amount | Date | Fee |
+----+-------+--------+------------+-----+
| 1 | Draw1 | 1500 | 2016-04-15 | 100 |
| 1 | Draw2 | 2000 | 2017-03-14 | 100 |
| 2 | Draw1 | 800 | 2018-04-16 | 150 |
| 2 | Draw2 | 760 | 2018-05-06 | 150 |
+----+-------+--------+------------+-----+