我有一个名为'transactions'的数据库表,其中有多列。对于每个事务行,我需要从指定列表中生成每列一行的导出
交易表
ID, DoNotEmail, DoNotMail, DoNotPhone, DoNotSMS 1000, true, false, true, true
以下规则需要适用。
设置DoNotEmail然后输出'DNE'
设置DoNotMail然后输出'DNM'
设置DoNotPhone然后输出'DNP'
设置DoNotSMS然后输出'DNS'
导出需要看起来像:
ID, Suppressions 1000, DNE 1000, DNP 1000, DNS
我真的很困惑,我能让它工作的唯一方法是将每个列插入两个临时表的插入语句非常可怕。 Urgh。
请问这可能吗?
感谢您的帮助。
的Darren
P.S。抱歉格式化。
答案 0 :(得分:6)
如果您只有四列,这可能会有效:
SELECT id,
'DNE' AS Suppressions
FROM transactions
WHERE donotemail = 'true'
UNION ALL
SELECT id,
'DNM' AS Suppressions
FROM transactions
WHERE donotmail = 'true'
UNION ALL
SELECT id,
'DNP' AS Suppressions
FROM transactions
WHERE donotphone = 'true'
UNION ALL
SELECT id,
'DNS' AS Suppressions
FROM transactions
WHERE donotsms = 'true'
答案 1 :(得分:6)
另一种可写方式是:
SELECT id,
case col
when 'DoNotEmail' then 'DNE'
when 'DoNotMail' then 'DNM'
when 'DoNotPhone' then 'DNP'
when 'DoNotSMS' then 'DNS'
end Suppressions
FROM
(
SELECT t.ID,
s.col,
CASE s.col
WHEN 'DoNotEmail' THEN DoNotEmail
WHEN 'DoNotMail' THEN DoNotMail
WHEN 'DoNotPhone' THEN DoNotPhone
WHEN 'DoNotSMS' THEN DoNotSMS
END AS DATA
FROM Transactions t
CROSS JOIN
(
SELECT 'DoNotEmail' AS col
UNION ALL SELECT 'DoNotMail'
UNION ALL SELECT 'DoNotPhone'
UNION ALL SELECT 'DoNotSMS'
) s
) s
where data = 'true';
由于您使用的是SQL Server,因此可以实现UNPIVOT
功能:
select id,
case col
when 'DoNotEmail' then 'DNE'
when 'DoNotMail' then 'DNM'
when 'DoNotPhone' then 'DNP'
when 'DoNotSMS' then 'DNS'
end Suppressions
from Transactions
unpivot
(
value
for col in ([DoNotEmail], [DoNotMail], [DoNotPhone], [DoNotSMS])
) piv
where value = 'true'
答案 2 :(得分:4)
这将在SQL Server 2008或更高版本中有效。如果需要,可以将其修改为在SQL Server 2005上运行。
select T1.ID,
T2.Name
from Transactions as T1
cross apply (values (DoNotEmail, 'DNE'),
(DoNotMail, 'DNM'),
(DoNotPhone, 'DNP'),
(DoNotSMS, 'DNS')
) as T2(Value, Name)
where T2.Value = 'true'
答案 3 :(得分:1)
四个记录表上的CROSS JOIN
可以节省四次扫描表。 bluefeet首先发布了一个答案(+1)。以下是使用Oracle的类似版本。
SELECT id, Suppressions FROM
(
SELECT id,
CASE
WHEN Col = 1 AND donotemail = 'true' THEN 'DNE'
WHEN Col = 2 AND donotmail = 'true' THEN 'DNM'
WHEN Col = 3 AND donotphone = 'true' THEN 'DNP'
WHEN Col = 4 AND donotsms = 'true' THEN 'DNS'
ELSE NULL
END Suppressions
FROM Transactions
CROSS JOIN (SELECT Level Col FROM dual CONNECT BY Level <=4)
)
WHERE Suppressions IS NOT NULL;
答案 4 :(得分:0)
select ID, 'DNE' as 'Suppressions'
from transactions
where DoNotEmail = 'true'
UNION ALL
select ID, 'DNM' as 'Suppressions'
from transactions
where DoNotMail = 'true'
UNION ALL
select ID, 'DNS' as 'Suppressions'
from transactions
where DoNotPhone = 'true'
UNION ALL
select ID, 'DNE' as 'Suppressions'
from transactions
where DoNotSMS = 'true'
order by ID