高级SQL GROUP BY查询

时间:2009-05-13 16:58:07

标签: sql sql-server

我的Items表'Category','Category2'中有两列,两列包含的信息基本相同。如果我设计了数据库,我会为类别创建一个单独的表,并根据该表添加项目到类别,不幸的是我没有创建数据库,我现在无法更改它,但我认为仍然存在做我想做的事。

该表的一个例子如下所示

Category             Category2
------------------   -----------------
truck                full size - pickup
full size - pickup   truck
Sedan                Import - Sedan
Convertible          Domestic - Coupe

我想运行一个查询来计算卡车,轿车,全尺寸 - 皮卡等的总数。我尝试了下面的查询,但它分别将两列分组

SELECT Category, Count(*) as Count
FROM Items
GROUP BY Category, Category2

5 个答案:

答案 0 :(得分:14)

在分组之前,只需将两个类别转储到一个列中。

SELECT Category, Count(*) as TheCount
FROM
(
  SELECT Category1 as Category
  FROM Items
  UNION ALL
  SELECT Category2
  FROM Items
) sub
GROUP BY Category

答案 1 :(得分:7)

想象一下,带有“category,category2”的行可以转换为两行(一行带有“category”,一行带有“category2”)来获得你想要的。你这样做是这样的:

SELECT items.category /* , other columns... */
FROM items
UNION ALL
SELECT items.category2 /* , other columns... */
FROM items

所以你需要做的就是聚合这些:

SELECT category, count(*) FROM (
    SELECT items.category FROM items
    UNION ALL
    SELECT items.category2 FROM items
    ) expanded
GROUP BY category

如果您的数据库支持,您也可以按照这样的阶段进行聚合:

with subcounts as (
  select items.category, items.category2, count(*) as subcount
  from items
  group by category, category2)
select category, sum(subagg) as finalcount from (
  select subcounts.category, sum(subcount) as subagg from subcounts group by category
  union all
  select subcounts.category2, sum(subcount) as subagg from subcounts group by category2
) combination
group by category

这将限制只对主项目表进行一次扫描,如果您只有少量类别则很好。您可以使用不支持“WITH ...”的数据库中的临时表来模拟相同的事情

编辑:

我确信必须有另一种方法可以在不扫描物品两次的情况下进行,并且有。好吧,这是PostgreSQL版本:

SELECT category, count(*) FROM (
  SELECT CASE selector WHEN 1 THEN category WHEN 2 THEN category2 END AS category
  FROM Items, generate_series(1,2) selector
) items_fixed GROUP BY category

这里唯一的postgresql特定位是“generate_series(1,2)”,它产生一个包含两行的“表” - 一行“1”,一行“2”。这是恕我直言,postgresql中最便捷的功能之一。当然,您也可以在SQL Server中实现类似的功能。或者你可以说“(选择1作为选择器联合全部选择2)”。另一种选择是“(values(1),(2))series(selector)”虽然这个语法有多少是标准的,多少是postgres特有的,但我不确定。这两种方法都有一个优势,即让计划者知道只有两行。

交叉连接此系列表项允许我们为每行项生成两个输出行。您甚至可以使用“items_fixed”子查询并使其成为视图 - 这与我倾向于尝试解决这些问题的过程相反。

答案 2 :(得分:2)

select category,sum(CategoryCount)
from(
select Category1 as category, count(Category1) as CategoryCount
from Table
group by Category1
union all
select Category2 as category, count(Category2) as CategoryCount
from Table
group by Category2) x
group by category

答案 3 :(得分:1)

我确定有更好的方法可以做到这一点,但是现在你去了

declare @group1 (Category1, Count int)
declare @group2 (Category2, Count int)

insert into @group1 (Category1, Count1)
select Category1, count(Category1)
from Table
group by Category1

insert into @group2 (Category2, Count2)
select Category2, count(Category2)
from Table
group by Category2

select 
coalesce(Category1, Category2) as Category,
coalesce(Count1,0) + coalesce(Count2,0) as CountAll
from @group1 a
    full outer join @group2 b
        on a.Category1=b.Category2

答案 4 :(得分:0)

试试这个

选择类型为1,count(*)作为来自表格的计数,其中类别为'%full size - pickup%'zh

联合

选择类型为2,count(*)作为来自表格的计数,其中类别为'%truck%'

联合

选择类型为3,count(*)作为来自表格的计数,其中类别为'%sedan%'  等等......

类型1将是您的全尺寸计数 输入您的卡车数量 等等......

希望这会有所帮助