2010-11-03 16 views
5

基本上我試圖在這個多維數據集結果中獲得不同的計數。但不幸的是,您不能使用Count(distinct(Field))與cube和rollup(as stated hereSQL Sever使用「分組...使用多維數據集」得到不同計數

以下是數據看起來像什麼。 (這只是一個簡單的例子,我期望在數據複製)

Category1  Category2  ItemId 
    a    b    1 
    a    b    1 
    a    a    1 
    a    a    2 
    a    c    1 
    a    b    2 
    a    b    3 
    a    c    2 
    a    a    1 
    a    a    3 
    a    c    4 

這裏是我想什麼做的,但它不工作。

SELECT 
    Category1, 
    Category2, 
    Count(Distinct(ItemId)) 
FROM ItemList IL 
GROUP BY 
    Category1, 
    Category2 
WITH CUBE 

我知道我可以做一個子選擇這樣得到我想要的結果:

SELECT 
    *, 
    (SELECT 
    Count(Distinct(ItemId)) 
    FROM ItemList IL2 
    WHERE 
    (Q1.Category1 IS NULL OR Q1.Category1 IS NOT NULL AND Q1.Category1 = IL2.Category1) 
    AND 
    (Q1.Category2 IS NULL OR Q1.Category2 IS NOT NULL AND Q1.Category2 = IL2.Category2)) 
     AS DistinctCountOfItems 
FROM (SELECT 
     Category1, 
     Category2 
     FROM ItemList IL 
     GROUP BY 
     Category1, 
     Category2 
     WITH CUBE) Q1 

但是,這時候的結果集是大運行速度慢,由於子選擇。有沒有其他方法可以從立方結果中獲得一個不同的計數?

這是我希望看到

Category1  Category2 DistinctCountOfItems 
a    a   3 
a    b   3 
a    c   3 
a    NULL   4 
NULL   NULL   4 
NULL   a   3 
NULL   b   3 
NULL   c   3 

回答

6

您應該能夠清理你的「混亂」的答案,像這樣:

select Category1, Category2, count(distinct ItemId) 
from ItemList 
group by Category1, Category2 
UNION ALL 
select Category1, null, count(distinct ItemId) 
from ItemList 
group by Category1 
UNION ALL 
select null, Category2, count(distinct ItemId) 
from ItemList 
group by Category2 
UNION ALL 
select null, null, count(distinct ItemId) 
from ItemList 

那麼其他的選項,我想出了:

select IL1.Category1, IL1.Category2, count(distinct ItemId) 
from ( 
    select Category1, Category2 
    from ItemList 
    group by Category1, Category2 
    with cube 
) IL1 
join ItemList IL2 on (IL1.Category1=IL2.Category1 and IL1.Category2=IL2.Category2) 
     or (IL1.Category1 is null and IL1.Category2=IL2.Category2) 
     or (IL1.Category2 is null and IL1.Category1=IL2.Category1) 
     or (IL1.Category1 is null and IL1.Category2 is null) 
group by IL1.Category1, IL1.Category2 

效率可能會因在索引上,被分組的列數等等。對於我寫的測試表,子選擇和聯接(與聯盟相對)略好一些。我目前無法訪問MSSQL 2000實例(我在2005年的一個實例中測試過),但我認爲這裏沒有任何東西是無效的。

UPDATE

一個更好的選擇,特別是如果你上進行分組超過2列(如果你在8列編組上面的代碼將需要256聯接子句來捕獲所有空組合! ):

select IL1.Category1, IL1.Category2, count(distinct ItemId) 
from ( 
    select Category1, Category2 
    from ItemList 
    group by Category1, Category2 
    with cube 
) IL1 
inner join ItemList IL2 on isnull(IL1.Category1,IL2.Category1)=IL2.Category1 
        and isnull(IL1.Category2,IL2.Category2)=IL2.Category2 
group by IL1.Category1, IL1.Category2 
+0

@ chezy525 ....不錯的做法...我喜歡它。它顯然比工會更有效率。仍然比我喜歡的更雜亂,但它的工作原理。 – 2010-11-12 18:29:09

+0

謝謝!這是我星期五的一個有趣的轉換!我認爲任何解決方案將會比應該「更雜亂」,沒有明確的總體支持... – chezy525 2010-11-12 19:21:19

+0

你最後的選擇是相同的,我最終會得到它,它是最優雅的一個,它的表最少以獲得結果。就我的執行計劃而言,根據Category1,Category2和ItemID的索引,查詢會盡可能快地進行。 – cairnz 2010-11-12 22:48:07

-1

這是非常有趣的結果。我可以在SQL Server 2008 R2中運行你的第一個查詢,但文檔說它不起作用。

這是您的第二個查詢的變體,可能會表現更好。它在子查詢和外查詢中使用了不同的計數

SELECT Category1, Category2, MAX(DistinctCount) as DistinctCount 
FROM (
    SELECT Category1, Category2, COUNT(DISTINCT ItemId) as DistinctCount 
    FROM ItemList 
    GROUP BY Category1, Category2 
    ) Q1 
GROUP BY Category1, Category2 
WITH CUBE 
+0

..實際上,當數據在表中被複制時,這不起作用。看看問題中修改後的數據。它不會返回所期望的。 – 2010-11-03 20:03:20

-1

這個怎麼樣?

內部查詢將返回不同的結果。

SELECT ORIGINAL_ITEM.Category1, DISTINCT_ITEM.Category2, DISTINCT_ITEM.cnt 
FROM 
    (SELECT DISTINCT category2, COUNT(*) as CNT 
    FROM ItemList) DISTINCT_ITEM 
JOIN ItemList ORIGINAL_ITEM on ORIGINAL_ITEM.category2 = DISTINCT_ITEM.category2 
GROUP BY ORIGINAL_ITEM.category1, DISTINCT_ITEM.category2 
+0

這甚至不是有效的......因此,您不能在組中的選擇列表中包含項目,這不包含在聚合或組by子句中。 – 2010-11-03 20:50:55

+0

同意。沒有實際測試過查詢。所以如果我添加了「group by」內部查詢,它是否是有效的想法? – exiter2000 2010-11-03 21:24:07

+0

不,它不會..謝謝嘗試 – 2010-11-03 23:03:11

-1

我有以下版本:

的Microsoft SQL Server 2008 R2(RTM) - 10.50.1600.1(英特爾X86)2010年4月2日15時53分02秒版權所有(c)Microsoft公司速成版在Windows NT 5.1高級服務(版本2600:Service Pack 3中)

當我運行查詢

SELECT 
    Category1, 
    Category2, 
    COUNT(DISTINCT(ItemId)) 
FROM ItemList IL 
GROUP BY 
    Category1, 
    Category2 
WITH CUBE 

我得到這些結果

a  a  3 
a  b  3 
a  c  3 
NULL a  3 
NULL b  3 
NULL c  3 
a  NULL 4 
NULL NULL 4 
+0

代碼Gunny Im意識到這可以在SQL Server 2008上工作。但我的問題是關於SQL Server 2000.您的帖子是無關緊要的 – 2010-11-08 00:45:42

+0

@John - 我想我需要更多地關注標籤,呵呵。 – 2010-11-08 00:48:40

1

這是我發現的另一種可能性,但它非常混亂。然而,它比使用子查詢運行得更快。

SELECT 
    category1, 
    category2, 
    count(distinct itemid) 
FROM (SELECT DISTINCT 
     category1, 
     category2, 
     itemid 
     FROM ItemList 
) x 
GROUP BY category1, category2 
UNION ALL 
SELECT 
    category1, 
    NULL, 
    count(distinct itemid) 
FROM (SELECT DISTINCT 
     category1, 
     category2, 
     itemid 
     FROM ItemList 
) x 
GROUP BY category1 
UNION ALL 
SELECT 
    NULL, 
    category2, 
    count(distinct itemid) 
FROM (SELECT DISTINCT 
     category1, 
     category2, 
     itemid 
     FROM ItemList 
) x 
GROUP BY category2 
UNION ALL 
SELECT 
    NULL, 
    NULL, 
    count(distinct itemid) 
FROM (SELECT DISTINCT 
     category1, 
     category2, 
     itemid 
     FROM ItemList 
) x 
相關問題