2010-07-14 39 views
3

我有一個結果,讓我值的範圍從我的數據庫查詢:是否可以按行組合?

Start  End 
-----  --- 
    1   3 
    5   6 
    137  139  

從這些,我需要查詢該範圍內的記錄,這可能會返回類似的數據庫:

Id Name 
----- ------ 
    1 foo 
    2 bar 
    3 baz 

Id Name 
----- ------ 
    5 foo 
    6 baz 

Id Name 
----- ------ 
    137 foo 
    138 bar 
    139 baz 

我想將這些結果分組,保留任何id範圍,因爲它們與相同的事物相關。例如,1-3是相同的137-139,所以它將有2的計數,但當然,在「範圍」可以是的2:

RangeStart RangeEnd Count 
---------- -------- ----- 
     137  139  2 
     5   6  1 

還要注意,爲了應該改變分組,所以foo/bar/baz與foo/baz/bar不一樣。

這是如何實現的?編輯:我有開始結果(開始,結束),我只關心最終結果(RangeStart,RangeEnd,Count)。我實際上並不需要中間結果,我只是用它們作爲解釋。

+0

爲什麼你有137,139,2而不是1,3,2? – 2010-07-14 20:09:13

+0

它可以是,我想爲簡單起見,你是對的,它應該是第一個'範圍',所以1,3,2也可以。我試圖指出,只要它指向正確的範圍,它並不重要。最後,我將顯示「foo,bar,baz,2」 – esac 2010-07-14 22:16:44

回答

3

這裏有兩個查詢:

  • 第一個連接了字符串 成基於所述範圍組和 然後示出了第一範圍爲每個 組串。它還有 字符串 出現的總次數。
  • 第二個顯示連接的 字符串及其各自的總計。

設置:

DECLARE @Tags TABLE ( 
    TagID INT, 
    Tag VARCHAR(3) 
) 

INSERT @Tags 
SELECT 1, 'Foo' UNION ALL 
SELECT 2, 'Bar' UNION ALL 
SELECT 3, 'Baz' UNION ALL 
SELECT 4, 'Foo' UNION ALL 
SELECT 5, 'Bar' UNION ALL 
SELECT 6, 'Baz' 

DECLARE @Ranges TABLE ( 
    StartRange INT, 
    EndRange INT 
) 

INSERT @Ranges 
SELECT 1,3 UNION ALL 
SELECT 2,3 UNION ALL 
SELECT 3,4 UNION ALL 
SELECT 4,6 

查詢,以顯示第一範圍和結果:

/* Get the first start and end ranges with a match and */ 
/* the total number of occurences of that match  */ 
SELECT 
    StartRange, 
    EndRange, 
    Total 
FROM (
    SELECT 
    StartRange, 
    EndRange, 
    Csv, 
    ROW_NUMBER() OVER (PARTITION BY Csv ORDER BY StartRange ASC) AS RowNum, 
    ROW_NUMBER() OVER (PARTITION BY Csv ORDER BY StartRange DESC) AS Total 
    FROM ( 
    /* For each range and its associated Tag values, */ 
    /* Concatenate the tags together using FOR XML */ 
    /* and the STUFF function      */ 
    SELECT 
     StartRange, 
     EndRange, 
     ( 
     SELECT STUFF( 
     (SELECT ',' + Tag 
     FROM @Tags WHERE TagID BETWEEN r.StartRange AND r.EndRange 
     ORDER BY TagID 
     FOR XML PATH('')),1,1,'') 
    ) AS Csv 
    FROM @Ranges r 
) t1 
) t2 
WHERE RowNum = 1 
ORDER BY StartRange, EndRange 

/* Results */ 

StartRange EndRange Total 
----------- ----------- ----- 
1   3   2 
2   3   1 
3   4   1 

查詢顯示concatenanted字符串和彙總:

/* Get the concatenated tags and their respective totals */ 
SELECT 
    Csv, 
    COUNT(*) AS Total 
FROM ( 
    /* For each range and its associated Tag values, */ 
    /* Concatenate the tags together using FOR XML */ 
    /* and the STUFF function      */ 
    SELECT 
    StartRange, 
    EndRange, 
    ( 
    SELECT STUFF( 
    (SELECT ',' + Tag 
    FROM @Tags WHERE TagID BETWEEN r.StartRange AND r.EndRange 
    ORDER BY TagID 
    FOR XML PATH('')),1,1,'') 
    ) AS Csv 
    FROM @Ranges r 
) t1 
GROUP BY Csv 
ORDER BY Csv 

/* Results */ 

Csv   Total 
------------ ----------- 
Bar,Baz  1 
Baz,Foo  1 
Foo,Bar,Baz 2 

字符串的concatentation方法禮貌Jeremiah Peschka

+0

好吧,讓它滿足我的需求,但我確實需要第一個序列範圍而不是CSV。我實際上將它綁定到BindingNavigator,並且隨着用戶循環,我查詢從StartRange到EndRange的名稱以顯示。對此有何幫助? – esac 2010-07-15 22:22:46

+0

我注意到了第一個查詢中的一些冗餘,並按照這種方式進行了更正。此外,該解決方案將受到對具有重複項的範圍行(即1,2和1,2)的保護。但大概可以用主鍵來處理。 – 8kb 2010-07-15 23:50:46

+0

應該說,「不會受到保護..」 – 8kb 2010-07-15 23:58:40

相關問題