2014-03-12 45 views
2

在我們的數據模型中有一個Person。基於值的存在的條件連接表

一個人住在一所房子裏。

一個人可以有一個'訂閱'。 (這與認購的構成無關)

房子可以有一個'訂閱'。

訂閱有訂閱號。

所以,這個datamodel允許一個人直接訂閱,但也可以通過他們的房子。

現在進行查詢。

如果該人通過他們的House進行了訂閱,則與該訂閱相關聯的SubscriptionNumber需要結果。如果不是這種情況,那麼與直接與Person相關的訂閱相關聯的SubscriptionNumber需要結果結果(如果該結果不存在,則爲NULL)。

該查詢的結果將顯示在網格中。我們允許用戶在此列上指定過濾和排序。這意味着兩件事情:

1) We cannot simply specify a CASE in the 'main' select statement and alias that result, 
     because this disallows us to filter on it, since WHERE is processed before SELECT. 
2) For the filtering to be meaningful the result has to be 'put' in one alias 

我真正的新DB開發和完全卡死,但是這是我想出直到如今

1) Using a query like this: 

     SELECT 
      (CASE 
       WHEN (House of person has subscription) 
       THEN (return subscription number of house) 
       ELSE (return subscription number of person) 
      END) AS SubscriptionNumber 
     This leaves me with the exception regarding the unknown column when i try to apply ordering on SubscriptionNumber. Is there some way to avoid this? 


2) Joining the 2 tables in the FROM list: 
     ... 
     FROM People 
     JOIN (...) AS HouseSubscriptionNumber 
     JOIN (...) AS PersonSubscriptionNumber 

     This leaves me with 2 seperate columns, which also disallows my ordering. 

我是什麼從概念上講,尋找是一種基於其存在提取任何一種方法的方法。 我一直在摸索與子查詢和工會和各種東西,但我總是得到某種腦循環:-(例如,我可以寫這樣的:

FROM People 
JOIN (
    SELECT 
     SubscriptionNumber = 
      CASE ... 
      END) 

但如何將我加入這主要查詢?

很多的問題! 是否有某種方式來做到這一點?

回答

8

最簡單的方法是CROSS APPLYCROSS APPLYFROM子句處理,並以它的別名可以像在正常表中的列名被重用:

SELECT 
... 
CxA.SubscriptionNumber 
FROM 
    MyTables 
CROSS APPLY 
    (SELECT CASE 
     WHEN (House of person has subscription) 
     THEN (return subscription number of house) 
     ELSE (return subscription number of person) 
    END) CxA(SubscriptionNumber) 

在該示例CxA是隻爲CROSS APPLY表達式(就像表別名的別名,做任何你想要的),並且SubscriptionNumber是列別名。

+1

經過一番測試,結果證明我的需求是一種更有序和更靈活的解決方案,因此我們接受了答案的變化。 – Apeiron

2

的關係是由因爲我沒有你的表定義。 這樣做是什麼,它去人桌子加入到房子桌子並且發現訂閱號碼(如果它存在如果它不存在,它將返回null)。它也會通過personID進入訂閱表並找到訂閱(如果存在,如果它不存在,則返回null)

然後我們使用COALESCE來查找第一個非空數字。如果兩個訂閱不存在,它將返回-1

SELECT COALESCE (su.SubscriptionNumber,s.subscriptionNumber,-1) as Target 
FROM Person AS p 
INNER JOIN house AS h ON p.houseid = h.houseid --assuming a person can only live in 1 house 

LEFT JOIN Subscription AS s ON p.subscriptionNumber = s.SubscriptionNumber 
LEFT JOIN Subscription AS su ON h.SubscriptionNubmer = su.SubscriptionNumber 
ORDER BY target DESC 

如果你想在你的榜樣使用方法1 where子句

SELECT TARGET FROM (
    SELECT COALESCE (su.SubscriptionNumber,s.subscriptionNumber,-1) as Target 
    FROM Person AS p 
    INNER JOIN house AS h ON p.houseid = h.houseid --assuming a person can only live in 1 house 

    LEFT JOIN Subscription AS s ON p.subscriptionNumber = s.SubscriptionNumber 
    LEFT JOIN Subscription AS su ON h.SubscriptionNubmer = su.SubscriptionNumber 
) as mark 
WHERE MARK.TARGET = XXXX 
+0

這不是強加我提到的同樣的問題嗎?如果用戶要在列上訂購,他應該投入什麼價值? – Apeiron

+0

爲了進一步澄清:我不能在where子句中使用此列。 – Apeiron

+0

@apeiron這將讓你訂購 – gh9