2015-10-12 110 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

希望它有幫助!