问题
I have the SQL query below:
create table #temp
(
Account varchar(5),
category varchar(6),
amount money
)
insert into #temp values ('A001', 'ABC-CO', 1000.00)
insert into #temp values ('A002', 'DEF-CR', 500.00)
insert into #temp values ('A002', 'GHI-PR', 800.00)
insert into #temp values ('A003', 'DEF', 700.00)
insert into #temp values ('A004', 'ABC-PR', 1100.00)
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(REPLACE(REPLACE(REPLACE(c.category, '-PR',''),'-
CO',''),'-CR',''))
FROM #temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT Account, ' + @cols + ', (case when DEF is not NULL and GHI is not NULL then 1
when ABC is not NULL then 1
else 0 end) as Outcome from
(
select Account
, amount
, REPLACE(REPLACE(REPLACE(category, ''-PR'',''''),''-CO'',''''),''-CR'','''') as
category
from #temp
) x
pivot
(
max(amount)
for category in (' + @cols + ')
) p '
execute(@query)
drop table #temp
Which generates the below table:
Account ABC DEF GHI Outcome
A001 1000.00 NULL NULL 1
A002 NULL 500.00 800.00 1
A003 NULL 700.00 NULL 0
A004 1100.00 NULL NULL 1
My issue is that the case statement is built off a known relationship where some of the columns do not appear in the query.
For example if I added to the case statement:
case when DEF is not NULL and JKL is not NULL then 1
The desired output is that since JKL doesn't exist, then 0.
Since JKL doesn't exist though, the query errors. How can I edit the code above to review table for column JKL, if it does not exist then add column JKL with NULL values, and then reference in case statement?
回答1:
the "columns" derive from the pivoted category values. Just insert dummy DEF, GHI, ABC categories for an account with NULL amount. Those null values will not affect the result and will generate the DEF, GHI, ABC columns if none of the accounts has those categories.
..........................
insert into #temp values ('A004', 'ABC-PR', 1100.00)
insert into #temp(Account, category, amount)
select a.Account, c.category, null
from
(
select top (1) Account from #temp
) as a
cross join (values('DEF'), ('GHI'), ('ABC'), ('JKL')) AS c(category);
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX);
.........................
来源:https://stackoverflow.com/questions/59632295/sql-dynamic-sql-add-column-if-it-does-not-exist