2014-06-17 69 views
0

嗨我很難在單個查詢中組合兩條記錄(來自單個表)。想法是,DATE_FIELD列是日期類型,ColA是整數數據類型。在一個選擇查詢中組合兩行

爲了進一步說明我的詢問,我附上圖片下面

enter image description here

1)是原始表。 2.)是所需的輸出。

P.S. DATE_FIELD的過濾器不是一個簡單的「WHERE DATE_FIELD IN」子句。

例如,我想獲得DATE_FIELD = 12/30/2013。然後,我需要獲得前九月DATE_FIELD還,這是2013年9月30日通過編程方式使用此查詢,我從網上得到:

CASE 
      WHEN MONTH(DATE_FIELD) < 10 
      THEN 
      (cast(CAST((DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
      ELSE 
      (cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
END 

這裏是我當前的SQL腳本(不能得到相當於可樂對於前九月過濾:

SELECT DATE_FIELD, ColA, 
CASE 
WHEN MONTH(DATE_FIELD) < 10 
THEN 
(cast(CAST((YEAR(DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
ELSE 
(cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
END AS PREVIOUS, 
(
SELECT ColA 
FROM TABLE_A 
WHERE DATE_FIELD = 
CASE 
    WHEN MONTH(DATE_FIELD) < 10 
    THEN 
    (cast(CAST((YEAR(DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    ELSE 
    (cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    END 
) AS PYE_colA 
FROM TABLE_A 
WHERE DATE_FIELD = '12/30/2013' 

感謝

+0

在這種情況下,國際海事組織,它的問題在那裏此查詢的輸出變,因爲合併數據這種方式並不一定是最優的。如果您計劃向用戶展示,那麼您寧願不將這種方式結合到查詢中,而是結合用戶界面。如果需要進入另一個數據庫,那麼從您的問題中可以看出,數據的基礎是什麼?請不要使用代碼,請用文字解釋您希望如何組合數據(即如何選擇合併在同一行中的日期)。 –

+0

您好奧默,主要目標是獲得所選日期和SEPT等效數據之間的平均值。我將更新圖像以描述如何選擇要組合的行。 – ChiSen

+0

我不明白你如何獲得數據。你從'12/30/2013'開始。該日期有兩條記錄。爲什麼你顯示99而不是0?它與StoreID有什麼關係(你沒有在你的查詢中使用)?那麼你如何從'12/30/2013'到'09/30/2013'?它總是在給定月份的最後一天減去三?或者你如何到達9月,特別是9月30日? –

回答

1

執行相同的操作檯上的交叉連接,只有在where子句中使用CASE結構:

SELECT a.DATE_FIELD AS DATE_FIELD_1, 
    a.ColA AS ColA_1, 
    b.DATE_FIELD AS DATE_FIELD_2, 
    b.ColA AS ColA_2 
FROM TABLE_A a 
CROSS JOIN TABLE_A b 
WHERE DATE_FIELD_1 = 'your date' 
AND DATE_FIELD_2 = (
    CASE 
    WHEN MONTH(DATE_FIELD_1) < 10 
    THEN 
     (cast(CAST((YEAR(DATE_FIELD_1) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    ELSE 
     (cast(CAST((YEAR(DATE_FIELD_1)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    END) 
; 

基於托爾斯滕Kettners言論另一種可能性:

SELECT a.DATE_FIELD AS DATE_FIELD_1, 
    a.ColA AS ColA_1, 
    b.DATE_FIELD AS DATE_FIELD_2, 
    b.ColA AS ColA_2 
FROM TABLE_A a 
INNER JOIN TABLE_A b 
ON b.DATE_FIELD = (
    CASE 
    WHEN MONTH(a.DATE_FIELD) < 10 
    THEN 
     (cast(CAST((YEAR(a.DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    ELSE 
     (cast(CAST((YEAR(a.DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date)) 
    END) 
WHERE a.DATE_FIELD = 'your date' 
; 
+2

這不是一個真正的交叉連接。這是一個內部連接:* AND ** b **。DATE_FIELD =(CASE ** a **。DATE_FIELD ...)*。您應該使用INNER JOIN,然後將該子句移到ON以更清楚地顯示您正在執行的操作。此外,在我看來,通過在WHERE子句中使用DATE_FIELD_1/2來模糊一些事情,而不是使用/ b.DATE_FIELD,這將更清楚地顯示您如何自我加入表。 –

+0

嗯,我認爲這是一個交叉連接,然後它的行被限制爲匹配我的WHERE子句。我理解這個錯誤嗎? –

+0

是的。交叉連接是你加入兩個表*無關*的地方。你建立一個所謂的笛卡爾產品。然而,就像你一樣,加入兩個*相關*(有標準如何匹配他們的記錄),你實際上做一個內部連接。只有你將其從讀者中隱藏起來(比如模仿不贊成使用的語法'FROM a,b WHERE a.x = b.y')。不要這樣做。 –