2013-10-18 40 views
0

我有四個表SQL服務器:重複加入4個表

  • Customers - PK:CustomerID
  • Events - PK:EventID
  • Customers_Events - 加入含一桌兩FK的CustomerIDEventID
  • Customer_Checkins - 包含一個時間戳列(CheckinDateTime)和一個FK參考CustomerID

我想這樣

CustomerName EventName CheckinDateTime 
------------ ---------- --------------- 
Peter   Christmas 2012-12-25 00:27:48.350 
Peter   Valentines 2013-02-14 01:19:36.113 
Peter   Spring  2013-05-20 02:13:53.710 

問題的輸出是,我得到這樣的結果,而不是

CustomerName EventName CheckinDateTime 
------------ ---------- --------------- 
Peter   Christmas 2012-12-25 00:27:48.350 
Peter   Christmas 2013-02-14 01:19:36.113 
Peter   Christmas 2013-05-20 02:13:53.710 
Peter   Valentines 2012-12-25 00:27:48.350 
Peter   Valentines 2013-02-14 01:19:36.113 
Peter   Valentines 2013-05-20 02:13:53.710 
Peter   Spring  2012-12-25 00:27:48.350 
Peter   Spring  2013-02-14 01:19:36.113 
Peter   Spring  2013-05-20 02:13:53.710 

每個有效記錄返回三次

這是我使用的腳本得到以上結果

SELECT DISTINCT 
    Customers.Firstname, Events.EventName, CustomerCheckins.CheckinDateTime 
FROM   
    CustomerCheckins 
INNER JOIN 
    Customers_Events ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
LEFT OUTER JOIN 
    Customers ON Customers_Events.CustomerID = Customers.CustomerID 
RIGHT OUTER JOIN 
    Events ON Customers_Events.EventID = Events.EventID 
WHERE  
    (Customers_Events.CustomerID = 1887) 

我真的很感謝一些幫助解決這個問題。我覺得我已經嘗試過劇本中的每一個組合。

回答

2

,您應該使用的distinctgrouping代替

SELECT Customers.Firstname, Events.EventName, MIN(CustomerCheckins.CheckinDateTime) 
FROM   
    CustomerCheckins 
     INNER JOIN Customers_Events ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
     INNER JOIN Customers ON Customers_Events.CustomerID = Customers.CustomerID 
     INNER JOIN Events ON Customers_Events.EventID = Events.EventID 
WHERE Customers_Events.CustomerID = 1887 
GROUP BY Customers.Firstname, Events.EventName 
+1

我不知道爲什麼你在哪裏downvoted。你提供的代碼實際上工作:-) - 除了一個小問題: 返回的三行中的時間戳都是一樣的 – Raydk

+1

由於我在我的回答中描述的原因,它沒有爲每個事件選擇正確的日期。 –

+0

Btw。分組和區別有什麼區別? – Raydk

1

問題是與你的數據庫設計。

您的數據模型不允許您將檢入與特定事件相關聯。

如果您的Event表包含startdate和enddate,則問題是可解的; 然後您可以在連接中添加時間限制。

編輯:

幸運的是,有一個在事件表中的開始日期和endate,所以下面的SQL應該工作:

  SELECT Customers.Firstname, Events.EventName, MAX(CustomerCheckins.CheckinDateTime) 
      FROM CustomerCheckins 
     INNER JOIN Customers_Events 
       ON CustomerCheckins.CustomerID = Customers_Events.CustomerID 
LEFT OUTER JOIN Customers 
       ON Customers_Events.CustomerID = Customers.CustomerID 
RIGHT OUTER JOIN Events 
       ON Customers_Events.EventID = Events.EventID 
      AND events.StartDateTime <= CustomerCheckins.CheckinDateTime 
      AND Events.EndDateTime > CustomerCheckins.CheckinDateTime 
      WHERE (Customers_Events.CustomerID = 1887) 
     GROUP BY Customers.Firstname, Events.EventName 

請注意,您在情況下,用戶需要在GROUP BY在事件中多次檢查。

對於checkindate,MIN或MAX的選擇取決於您希望在事件期間顯示第一個還是最後一個簽入。

旁註:

我不是很熟悉的SQL Server查詢優化,但它可能難以它來創建此查詢一個很好的執行計劃。 如果您打算在實時系統中使用它,請務必在加載大量數據表後對其進行測試。

+0

我剛刷新頁面並看到了您的答案。 我的事件表確實包含一個startdate和enddate。 添加這樣的約束就足夠了嗎? AND events.StartDateTime <= CustomerCheckins.CheckinDateTime – Raydk

+1

是的,但您在startdate和enddate上都需要它。 –

+0

當然可以。它應該是Events.EndDateTime> CustomerCheckins.CheckinDateTime – Raydk