2009-06-16 162 views
1

說我有這樣的表在我的MSSQL Server 2005服務器集團通過與伯爵

Apples 
+ Id 
+ Brand 
+ HasWorms 

現在我想每品牌有蟲子在他們的蘋果數量的概述。
事實上,如果它們未被破壞,那麼更好的辦法是列出所有帶有國旗的蘋果品牌。

所以,如果我有數據

ID| Brand  | HasWorms 
--------------------------- 
1 | Granny Smith | 1 
2 | Granny Smith | 0 
3 | Granny Smith | 1 
4 | Jonagold  | 0 
5 | Jonagold  | 0 
6 | Gala   | 1 
7 | Gala   | 1 

我想

Brand  | IsUnspoiled 
-------------------------- 
Granny Smith | 0 
Jonagold  | 1 
Gala   | 0 

落得我想我應該先

select brand, numberOfSpoiles = 
    case 
     when count([someMagic]) > 0 then 1 
     else 0 
    end 
from apples 
group by brand 

我不能使用having子句,因爲那時沒有有效參賽作品的品牌會從我的名單中消失(我不會看到參賽聯歡晚會)。
然後,我認爲某種子查詢應該這樣做,但我無法將外部(分組)查詢的蘋果ID鏈接到內部(計數)查詢...

任何想法?

+0

你不只是愛我的ASCII表嗎? – 2009-06-16 15:31:53

+1

@boris:如果您告訴我們您正在使用哪種RDBMS,我們會更加愛他們。 – Quassnoi 2009-06-16 15:37:01

+0

當然,我的不好。編輯OP – 2009-06-17 07:26:39

回答

2

SQL Server版本,我沒有被寵壞,而不是未受污染的,這樣我可以使用SIGN功能,使代碼更短

表+數據(DML + DDL)

create table Apples(id int,brand varchar(20),HasWorms bit) 

insert Apples values(1,'Granny Smith',1) 
insert Apples values(2,'Granny Smith',0) 
insert Apples values(3,'Granny Smith',1) 
insert Apples values(4,'Jonagold',0) 
insert Apples values(5,'Jonagold',0) 
insert Apples values(6,'Gala',1) 
insert Apples values(7,'Gala',1) 

查詢

select brand, IsSpoiled = sign(sum(convert(int,hasworms))) 
from apples 
group by brand 

輸出

brand IsSpoiled 
---------------------- 
Gala 1 
Granny Smith 1 
Jonagold 0 
3
select brand, case when sum(hasworms)>0 then 0 else 1 end IsUnSpoiled 
from apples 
group by brand 
+0

除了字段名稱和一些間距的外殼,它與我到達的地址完全相同...... :) – Guffa 2009-06-16 15:42:40

1
SELECT brand, 
     COALESCE(
     (
     SELECT TOP 1 0 
     FROM apples ai 
     WHERE ai.brand = ao.brand 
       AND hasWorms = 1 
     ), 1) AS isUnspoiled 
FROM (
     SELECT DISTINCT brand 
     FROM apples 
     ) ao 

如果您有(brand, hasWorms)索引,該查詢將是超級快,因爲它不指望聚集,而是搜索每個品牌ANS站內的第一寵壞的蘋果。

0
SELECT CASE WHEN SUM(HasWorms) > 0 THEN 0 ELSE 1 END AS IsUnspoiled, Brand 
FROM apples 
GROUP BY Brand 
1
SELECT Brand, 
     1-MAX(HasWorms) AS IsUnspoiled 
FROM apples 
GROUP BY Brand 
0

我還沒有測試過這個,也許我錯過了一些東西。但是這不會工作嗎?

SELECT Brand, SUM(CONVERT(int, HasWorms)) AS SpoiledCount 
FROM Apples 
GROUP BY Brand 
ORDER BY SpoiledCount DESC 

我假設HasWorms是一個位域,因此是CONVERT語句。這應該會返回一個品牌清單,其中包括每個品牌被寵壞的蘋果數量。你應該看到最糟糕的(最糟糕的)在頂部和最好的底部。

0

有很多方法來剝皮這隻貓。根據你的RDBMS,不同的查詢會給你最好的結果。在我們的Oracle盒子裏,這個查詢的執行速度比列出的其他所有更快,假設你有一個蘋果品牌表的索引(品牌索引,HasWorms更快,但可能不太可能;這取決於你的數據分佈,HasWorms的指數可能是最快的)。它還假設你有一個「BrandTable」表,它只有品牌:

SELECT Brand 
    , 1 IsSpoiled 
    FROM BrandTable b 
WHERE EXISTS 
     (SELECT 1 
      FROM Apples a 
      WHERE a.brand = b.brand 
      AND a.HasWorms = 1 
     ) 
UNION 
SELECT Brand 
    , 0 
    FROM BrandTable b 
WHERE NOT EXISTS 
     (SELECT 1 
      FROM Apples a 
      WHERE a.brand = b.brand 
      AND a.HasWorms = 1 
     ) 
ORDER BY 1;