2014-01-30 38 views
0

我與發展中國家的查詢,從每個月比較單一表更改月份掙扎,例如數據 -SQL Server查詢,看看從一個月什麼改爲一個月

+-----------------------------------------------------------+  
| TaxGroupDetails           | 
+-----------+--+----------+--+-----------+--+---------------+ 
| Tax Group | | Tax Type | | Geocode | | EffectiveDate | 
+-----------+--+----------+--+-----------+--+---------------+ 
|  2001 | | 1D  | | 440011111 | |  1120531 | 
|  2001 | | X1  | | 440011111 | |  1120531 | 
|  2001 | | D3  | | 440011111 | |  1120531 | 
|  2001 | | DGH  | | 440011111 | |  1120531 | 
|  2001 | | 1D  | | 440011111 | |  1130101 | 
|  2001 | | X1  | | 440011111 | |  1130101 | 
|  2001 | | D3  | | 440011111 | |  1130101 | 
|  2001 | | 1D  | | 440011111 | |  1140201 | 
|  2001 | | X1  | | 440011111 | |  1140201 | 
|  2001 | | D3  | | 440011111 | |  1140201 | 
|  2001 | | Z9  | | 440011111 | |  1140201 | 
+-----------+--+----------+--+-----------+--+---------------+ 

我希望看到的變化該表是什麼在稅收組中添加或刪除的,在前兩個生效日期之間。

如果我在今年2月(1140201)運行查詢,我試圖根據樣本數據獲得的結果將是Z9(已添加)。

如果我是跑在去年一月的查詢(1130101)我希望看到DGH(刪除)

我希望兩個單獨的查詢,一個顯示被添加的內容,另一個是展示什麼除去。

我已經嘗試了多種途徑來提出這兩個查詢,但似乎無法獲得正確的結果。任何人都可以將我指向正確的方向嗎?

+2

1140201 =二月?領先的1是什麼?爲什麼不是EffectiveDate DATE列? –

+0

抱歉,格式在我的示例中很糟糕 - 遺留系統以這種方式存儲日期,SQL Server中的數字列不是真正的日期字段。 – user3255010

+0

格式化看起來不錯,我已經編輯了你的格式化問題。訣竅是在行的開頭有四個空格,以便將其格式化爲代碼。 –

回答

0
SELECT 
     Current.TaxGroup, 
     Current.TaxType, 
     Current.GeoCode, 
     'Added' 
    FROM 
     TaxGroupDetails AS Current 
    WHERE 
     Current.EffectiveDate = @CurrentPeriod AND 
     NOT EXISTS 
     (
      SELECT * 
      FROM TaxGroupDetails As Previous 
      WHERE 
       Previous.EffectiveDate = @PreviousPeriod 
       Current.TaxGroup = Previous.TaxGroup and 
       Current.TaxType = Previous.TaxType and 
       Current.GeoCode = Previous.GeoCode 
     ) 

    UNION ALL 

    SELECT 
     Current.TaxGroup, 
     Current.TaxType, 
     Current.GeoCode, 
     'Added' 
    FROM 
     TaxGroupDetails AS Previous 
    WHERE 
     Previous.EffectiveDate = @PreviousPeriod AND 

     NOT EXISTS 
     (
      SELECT * 
      FROM TaxGroupDetails As Current 
      WHERE 
       Current.EffectiveDate = @CurrentPeriod 
       Current.TaxGroup = Previous.TaxGroup and 
       Current.TaxType = Previous.TaxType and 
       Current.GeoCode = Previous.GeoCode 
     ) 
0

基於集合的解決方案:取整個表格和整個表格之間的差異,並將所有日期向前推進一個時間間隔。這將消除除「新」代碼之外的所有行。

SELECT 
    [TaxGroup], 
    [Tax Type], 
    [EffectiveDate] 
FROM TaxGroupDetails t 
EXCEPT 
SELECT 
    [TaxGroup], 
    [Tax Type], 
    (SELECT MIN([EffectiveDate]) 
    FROM TaxGroupDetails 
    WHERE [EffectiveDate] > t.[EffectiveDate] 
     AND [TaxGroup] = t.[TaxGroup] 
) 
FROM TaxGroupDetails t 

要查看得到刪除的內容,請反向投影。將子查詢更改爲:

SELECT MAX([EffectiveDate]) 
    FROM TaxGroupDetails 
    WHERE [EffectiveDate] < t.[EffectiveDate] 
     AND [TaxGroup] = t.[TaxGroup] 
0

正如您所說,您需要兩個查詢,一個用於選擇要比較的兩組數據中的每一個。

SELECT [Tax Group], [Tax Type], [Geocode], [EffectiveDate] 
FROM TaxGroupDetails 
WHERE EffectiveDate = 1120531 

SELECT [Tax Group], [Tax Type], [Geocode], [EffectiveDate] 
FROM TaxGroupDetails 
WHERE EffectiveDate = 1140201 

然後你需要加入這兩者結合起來使用某種形式的關鍵,稅收組的組合和稅收類型似乎是合理的位置。

SELECT * 
FROM 
(
    SELECT [Tax Group], [Tax Type], [Geocode], [EffectiveDate] 
    FROM TaxGroupDetails 
    WHERE EffectiveDate = 1120531 
) AS FirstGroup 

FULL OUTER JOIN  

(
    SELECT [Tax Group], [Tax Type], [Geocode], [EffectiveDate] 
    FROM TaxGroupDetails 
    WHERE EffectiveDate = 1140201 
) AS SecondGroup 

ON FirstGroup.[Tax Group] = SecondGroup.[Tax Group] 
AND FirstGroup.[Tax Type] = SecondGroup.[Tax Type] 

這裏的FULL OUTER JOIN告訴SQL在其他行不存在時包含剩餘行。

最後,讓我們整理和排序的列,而不是使用*:

SELECT COALESCE(FirstGroup.[Tax Group], SecondGroup.[Tax Group]), 
    COALESCE(FirstGroup.[Tax Type], SecondGroup.[Tax Type]), 
    FirstGroup.Geocode, SecondGroup.Geocode, 
    FirstGroup.EffectiveDate, SecondGroup.EffectiveDate 
FROM 
. 
. 
. 

COALESCE從第一個匹配列刪除空值和我們說這些muct等於有證據顯示這兩個副本沒有意義。

0

如果你有SQL2012:

WITH t AS (
    SELECT *, 
    ROW_NUMBER() OVER(PARTITION BY [TaxGroup], [Tax Type] ORDER BY [EffectiveDate] ASC) rownum 
    FROM [TaxGroup] 
) 
SELECT * 
FROM t 
WHERE rownum = 1 
    AND [EffectiveDate] = @Date 

爲了得到其他的查詢,更改ASC爲desc

0

試試這個/你可以從這個[局部]解決方案啓動:

DECLARE @MyTable TABLE (
    ID INT IDENTITY PRIMARY KEY, 
    [Tax Group] SMALLINT NOT NULL, 
    [Tax Type] VARCHAR(3) NOT NULL, 
    [Geocode] INT NOT NULL, 
    [EffectiveDate] INT NOT NULL 
); 

INSERT @MyTable 
      SELECT 2001, '1D ', 440011111, 1120531 
UNION ALL SELECT 2001, 'X1 ', 440011111, 1120531 
UNION ALL SELECT 2001, 'D3 ', 440011111, 1120531 
UNION ALL SELECT 2001, 'DGH', 440011111, 1120531 
UNION ALL SELECT 2001, '1D ', 440011111, 1130101 
UNION ALL SELECT 2001, 'X1 ', 440011111, 1130101 
UNION ALL SELECT 2001, 'D3 ', 440011111, 1130101 
UNION ALL SELECT 2001, '1D ', 440011111, 1140201 
UNION ALL SELECT 2001, 'X1 ', 440011111, 1140201 
UNION ALL SELECT 2001, 'D3 ', 440011111, 1140201 
UNION ALL SELECT 2001, 'Z9 ', 440011111, 1140201; 

DECLARE @Results TABLE (
    ID INT NOT NULL, 
    Rnk INT NOT NULL, 
    EffectiveYear SMALLINT NOT NULL, 
     PRIMARY KEY (Rnk, EffectiveYear) 
); 
INSERT @Results 
SELECT x.ID, 
     DENSE_RANK() OVER(ORDER BY x.[Tax Group], x.[Tax Type], x.[Geocode]) AS Rnk, 
     x.EffectiveDate/10000 AS EffectiveYear 
FROM @MyTable x; 

SELECT 
     crt.*, 
     prev.*, 
     CASE 
      WHEN crt.ID IS NOT NULL AND prev.ID IS NOT NULL THEN '-' -- No change 
      WHEN crt.ID IS NULL AND prev.ID IS NOT NULL THEN 'D' -- Deleted 
      WHEN crt.ID IS NOT NULL AND prev.ID IS NULL THEN 'I' -- Inserted 
     END AS RowStatus 
FROM @Results crt FULL OUTER JOIN @Results prev ON crt.Rnk = prev.Rnk 
AND  crt.EffectiveYear - 1 = prev.EffectiveYear 
ORDER BY ISNULL(crt.EffectiveYear - 1, prev.EffectiveYear), crt.Rnk; 

樣品輸出:

---- ---- ------------- ---- ---- ------------- 
|  Current data | | Previous data | 
---- ---- ------------- ---- ---- ------------- --------- 
ID Rnk EffectiveYear ID Rnk EffectiveYear RowStatus 
---- ---- ------------- ---- ---- ------------- --------- 
1 1 112   NULL NULL NULL   I -- Current vs. previous: current row hasn't a previous row 
3 2 112   NULL NULL NULL   I -- the same thing 
4 3 112   NULL NULL NULL   I -- the same thing 
2 4 112   NULL NULL NULL   I -- the same thing 
NULL NULL NULL   4 3 112   D <-- Deleted: ID 4 = 'DGH' 
5 1 113   1 1 112   - -- there is no change 
7 2 113   3 2 112   - 
6 4 113   2 4 112   - 
8 1 114   5 1 113   - 
10 2 114   7 2 113   - 
9 4 114   6 4 113   - 
11 5 114   NULL NULL NULL   I <-- Inserted: ID 11 = 'Z9' 
NULL NULL NULL   8 1 114   D 
NULL NULL NULL   10 2 114   D 
NULL NULL NULL   9 4 114   D 
NULL NULL NULL   11 5 114   D 

注:我假設一年內沒有重複行(x.[Tax Group], x.[Tax Type], x.[Geocode])。