2015-10-12 111 views
0

我试图根据列中的值将结果集中的列拆分为2列。 因此,用户可以订阅多个项目,用户可以拥有2个可以接收此订阅的电子邮件地址。 结果集给出订阅电子邮件ID的订阅及其相应条目的列表。SQL - 根据值拆分列

DB细节

Table 1 - user_subscriptions 

user_id 
email_id - 1 for email id 1 and 2 for email id 2 
subscription_id 

Table 2 - subscriptions 

subscription_id 
subscription_name 

现在我需要无论是通过任一电子邮件ID或不认缴的该用户的所有预订。 所以我得到一个结果集是这样的

+----------------------+----------+ 
| subscription_name | email_id | 
+----------------------+----------+ 
| item1    | 1  | 
| item1    | 2  | 
| item2    | null  | 
| item3    | 1  | 
| item4    | null  | 
| item5    | 2  | 
+----------------------+----------+ 

于是我找下面

+-------------------+---------+---------+ 
| subscription_name | email_1 | email_2 | 

+-------------------+---------+---------+ 
| item1    | 1 or Y | 1 or Y | 
| item2    | 0 or N | 0  | 
| item3    | 1  | 0  | 
| item4    | 0  | 0  | 
| item5    | 0  | 1  | 
+-------------------+---------+---------+ 

希望这个问题有意义分割上述结果集到类似。任何帮助,将不胜感激!

更新-----------

样本数据:

subscriptions - +-----------------+-------------------+ | subscription_id | subscription_name | +-----------------+-------------------+ | 1 | item1 | | 2 | item2 | | 3 | item3 | | 4 | item4 | | 5 | item5 | +-----------------+-------------------+

user_subscriptions

+---------+----------+-----------------+ | user_id | email_id | subscription_id | +---------+----------+-----------------+ | 101 | 1 | 1 | | 101 | 2 | 1 | | 101 | 1 | 3 | | 101 | 2 | 5 | | 102 | 1 | 1 | | 102 | 2 | 1 | +---------+----------+-----------------+

预期结果:

对于user_id = 101

+-----------------+-------------------+--------+--------+ | subscription_id | subscription_name | mail_1 | mail_2 | +-----------------+-------------------+--------+--------+ | 1 | item1 | Y | Y | | 2 | item2 | N | N | | 3 | item3 | Y | N | | 4 | item4 | N | N | | 5 | item5 | N | Y | +-----------------+-------------------+--------+--------+

+0

什么意思'1或Y'和'0或N'在你想要的输出中? –

+0

如果订阅的结果是1或Y.它只是我希望输出的格式。现在它可以是1,如果订阅,或者0,如果不订阅。 – Zuke

+0

根据我的回答下面 - 我会检查这个:http://stackoverflow.com/a/8114446/817132 - 这可能会给你一个清晰的答案特别是sybase。 – wally

回答

1
SELECT 
    S.subscription_id, 
    S.subscription_name, 
    CASE 
     WHEN US1.mail_ID IS NULL THEN 'N' 
     ELSE 'Y' 
    END mail_1, 
    CASE 
     WHEN US2.mail_ID IS NULL THEN 'N' 
     ELSE 'Y' 
    END mail_2 
FROM subscriptions S 
LEFT JOIN user_subscriptions US1 
    ON S.subscription_id = US1.subscription_id 
AND US1.mail_id = 1 
LEFT JOIN user_subscriptions US2 
    ON S.subscription_id = US2.subscription_id 
AND US2.mail_id = 2 
WHERE us1.user_id = 5 -- or use a variable @user_ID 
    OR us2.user_id = 5 
+0

嗨胡安,这两个表都没有通过user_id链接。它们使用subscription_id链接。 – Zuke

+0

对不起,我现在会修复它 –

+0

:)我接近我想从这个解决方案胡安但我想获得订阅只有一个user_id。帮帮我? – Zuke

1

你需要一个条件骨料:

select us.subscription_name, 
    -- there's at least one email 
    CASE WHEN MIN(us.email_id) IS NOT NULL THEN 'Y' ELSE 'N' END as email_1, 
    -- there's more than one email 
    CASE WHEN MIN(us.email_id) <> MAX(us.email_id) THEN 'Y' ELSE 'N' END as email_2 
from subscriptions as s 
left join user_subscriptions as us 
on s.subscription_id = us.subscription_id 
where us.user_id = ... 
group by us.subscription_name 
+0

你好,检查项目5的情况下,我认为你的查询将显示'1 - 0',而不是OP样本'0 - 1' –

+0

@JuanCarlosOropeza:如果这些'id'实际上是'0'和'1',很容易用'MIN = 1'和'MAX = 2'重写。 OP需要添加更多关于实际数据的详细信息... – dnoeth

+0

@dnoeth - 值可以是1或0.我可以在代码中处理它。 – Zuke

0

我不是Sybase合作过,但我确信下面的SQL将很容易转化(甚至运行直接):

SELECT 
    s.subscription_name, 
    COUNT(email_1.subscription_id) AS email_1, 
    COUNT(email_2.subscription_id) AS email_2 
FROM subscriptions AS s 
LEFT JOIN user_subscriptions AS email_1 ON (
    s.subscription_id = email_1.subscription_id AND 
    email_1.email_id = 1 
) 
LEFT JOIN user_subscriptions AS email_2 ON (
    s.subscription_id = email_2.subscription_id AND 
    email_2.email_id = 2 
) 
; 

你也可以说IF(email_1.subscription_id IS NOT NULL, 'Y', 'N')等在SELECT返回一个直接的是/否,而不是一个计数等

它工作的原理是的LEFT JOIN发言名单将匹配任何“用户订阅”纪录email_id=1email_id=2

我缺乏sybase知识免责声明: ANSI SQL无法执行PIVOT - 如果使用sybase,那么我可以做得更加优雅。还有另外一个问题+答案,暗示sybase可以做这样的事情;它值得你一边看:https://stackoverflow.com/a/8114446/817132

希望它有帮助!