2016-10-05 119 views
0

我正在使用SQLServer2008,並遇到了我從未見過的問題。我有一個數據集,其中一些值每季度重複多次。我試圖選擇每個季度最新的價值。根據連接表中的不同字段選擇最新值

SELECT PPAV.BusinessID 
         , (cast(year(PPAV.PartnerAttributeValueStartDate) as char(4)) + '0' + cast(datepart(qq, PPAV.PartnerAttributeValueStartDate) as char(1))) AS Quarter 
         , PAV.PartnerAttributeValue 
        FROM Partner_PartnerAttributeValue PPAV 
        JOIN PartnerAttributeValue PAV 
         ON PAV.PartnerAttributeValueID = PPAV.PartnerAttributeValueID 
        WHERE PAV.PartnerAttributeID = 7 
         AND (PPAV.PartnerAttributeValueID = 22 OR PPAV.PartnerAttributeValueID = 795 OR PPAV.PartnerAttributeValueID = 796) 

        GROUP BY PPAV.BusinessID 
          , (cast(year(PPAV.PartnerAttributeValueStartDate) as char(4)) + '0' + cast(datepart(qq, PPAV.PartnerAttributeValueStartDate) as char(1))) 
          , PAV.PartnerAttributeValue 

這是發生問題的代碼。我只需要每個季度一個價值。有時候季度有變化,信息是重複的。當我試圖補救這個問題時,我使用這個代碼,並且通過使問題Quarter有4個值,實際上使問題變得更糟。

SELECT PPAV.BusinessID 
         , (cast(year(PPAV.PartnerAttributeValueStartDate) as char(4)) + '0' + cast(datepart(qq, PPAV.PartnerAttributeValueStartDate) as char(1))) AS Quarter 
         , CASE WHEN (cast(year(PPAV.PartnerAttributeValueStartDate) as char(4)) + '0' + cast(datepart(qq, PPAV.PartnerAttributeValueStartDate) as char(1))) = (cast(year(PPAV.PartnerAttributeValueStartDate) as char(4)) + '0' + cast(datepart(qq, PPAV.PartnerAttributeValueStartDate) as char(1))) 
          THEN SubHist.PartnerAttributeValue 
          ELSE PAV.PartnerAttributeValue 
          END AS PartnerAttributeValue 
       FROM Partner_PartnerAttributeValue PPAV 
       JOIN PartnerAttributeValue PAV 
        ON PAV.PartnerAttributeValueID = PPAV.PartnerAttributeValueID 
       JOIN (SELECT PPAV.BusinessID 
            , MAX(PPAV.PartnerAttributeValueStartDate) AS MAX 
            , PAV.PartnerAttributeValue 
           FROM Partner_PartnerAttributeValue PPAV 
           JOIN PartnerAttributeValue PAV 
            ON PAV.PartnerAttributeValueID = PPAV.PartnerAttributeValueID 
           WHERE PAV.PartnerAttributeID = 7 
           AND (PPAV.PartnerAttributeValueID = 22 OR PPAV.PartnerAttributeValueID = 795 OR PPAV.PartnerAttributeValueID = 796) 
           GROUP BY PAV.PartnerAttributeValue 
             ,PPAV.BusinessID 
         )SubHist 
        ON SubHist.BusinessID = PPAV.BusinessID 
       WHERE PAV.PartnerAttributeID = 7 
        AND (PPAV.PartnerAttributeValueID = 22 OR PPAV.PartnerAttributeValueID = 795 OR PPAV.PartnerAttributeValueID = 796) 
       GROUP BY PPAV.BusinessID 
         , (cast(year(PPAV.PartnerAttributeValueStartDate) as char(4)) + '0' + cast(datepart(qq, PPAV.PartnerAttributeValueStartDate) as char(1))) 
         , PAV.PartnerAttributeValue 
         , SubHist.PartnerAttributeValue 

我很不確定我做了什麼使問題變得更糟。我想到了我的CASE WHEN語句從附加連​​接表中刪除會修復它。

任何幫助,非常感謝!

下面是我試圖消除

4356 201501 REGISTERED 
4356 201502 REGISTERED 
4356 201503 REGISTERED 
4356 201504 REGISTERED 
4356 201601 GOLD 
4356 201601 REGISTERED 
4356 201602 REGISTERED 
4356 201603 REGISTERED 
4356 201604 REGISTERED 

的問題就是2016年第一季度有多個值,得到的數據,由於是扭曲一些樣本數據。應該只有黃金價值,而不是黃金和註冊

謝謝!

+0

您希望每個季度有一個值,但可能超過季度中的一個值,我認爲您需要使用聚合函數,例如SUM。 –

+0

似乎你可以使用一個窗口函數,例如row_number()over(由BusinessID分區,季度,由PartnerAttributeValueStartDate desc命令)RN'將其包裝在子標題或cte中,然後添加'Where RN = 1' – xQbert

+0

Im not sure總和會起作用。這只是較大查詢的一小部分。該值是一個字符值,所以當宿舍相等時,我需要最大日期的字符值。此查詢只是使用ROW_number技巧的較大CTE的一部分,較大函數的性能已經非常差:( – Gollathor

回答

2

使用窗口函數爲每個季度和業務ID生成行號。然後限制到每個組的第一行號(RN)...

由於必須先生成RN,然後才能限制它,我們將它包裝在CTE或子查詢中,然後應用RN = 1 .. 。

我也:

  1. 交換你的OR語句是爲了可讀性和可能的​​性能IN。
  2. 將季度計算修改爲使用concat而不是+字符串聚合。 (依靠隱式轉換,如果處理有效日期應該沒問題)

這些附加更改中的任何一個都可能引入了語法錯誤。

UNTESTED如果在SQL Fiddle中提供了下面和示例數據的表結構,我會測試它。

Select * from (

    SELECT PPAV.BusinessID 
     , concat(year(PPAV.PartnerAttributeValueStartDate) 
        , '0' 
        ,datepart(qq, PPAV.PartnerAttributeValueStartDate) 
       ) 
      AS Quarter 
     , PAV.PartnerAttributeValue 
     , row_number() 
      Over (PARTITION BY PPAV.BusinessID 
       , year(PPAV.PartnerAttributeValueStartDate) 
       , datepart(qq, PPAV.PartnerAttributeValueStartDate)) 
       ORDER BY PartnerAttributeValueStartDate DESC) RN 
    FROM Partner_PartnerAttributeValue PPAV 
    JOIN PartnerAttributeValue PAV 
     ON PAV.PartnerAttributeValueID = PPAV.PartnerAttributeValueID 
    WHERE PAV.PartnerAttributeID = 7 
     AND PPAV.PartnerAttributeValueID IN (22, 795,796) 
    GROUP BY PPAV.BusinessID 
      , concat(year(PPAV.PartnerAttributeValueStartDate) 
        , '0' 
        ,datepart(qq, PPAV.PartnerAttributeValueStartDate) 
       ) 
      , PAV.PartnerAttributeValue) cte 

from cte where RN = 1 
+0

我可能只是將年份和季度部分分開,而不會將它們重新組合。這樣做是否有優勢?與'group by'同樣的故事,對吧? – shawnt00

+0

沒有好處...我應該按開始日期desc排序,而不是允許默認的asc ... – xQbert

+0

我不認爲我可以在一個子隊列中運行一個CTE。我應該更具體的事實,這個查詢是從一個更大的查詢 – Gollathor

相關問題