2009-06-16 101 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;