双重计算两个表

时间:2015-03-12 10:06:10

标签: sql sql-server

我有两张桌子:

create table creations (id int)
create table images (creation_id int, path varchar)

images.path中,可用的值有限,例如“我的文档”,“桌面”等(它是数据挖掘数据库)。

我想找到创作的不同路径的数量,以及有多少创作有这么多路径。

有了这些数据:

insert into creations (id) values (1), (2), (3), (4)
insert into images (creation_id, path) values
(1, 'a'), (1, 'a'), (1, 'a'), --creation 1: 1 path
(2, 'a'), (2, 'b'), (2, 'a'), --creation 2: 2 paths
(3, 'a'), (3, 'b'), (3, 'c'), --creation 3: 3 paths
(4, 'a'), (4, 'a'), (4, 'b') --creation 4: 3 paths

期望的结果如下所示:

nb_paths | nb_creations
-----------------------
1        | 1
2        | 2
3        | 1

3 个答案:

答案 0 :(得分:3)

我不确定我理解这个问题,也不确定为什么你提供了一个查询作为答案。

但是我建议将相关查询移到APPLY中。下面我使用了OUTER APPLY,它允许所有创建记录,即使在路径中找不到。交叉应用会将结果限制为仅在路径中找到的创建。

SELECT
    nb_path
  , COUNT(*) AS nb_creations
FROM (
        SELECT
            c.id
          , COALESCE(oa.nb_path, 0) nb_path
        FROM creations AS c
            OUTER APPLY (
                    SELECT
                        COUNT(DISTINCT [path])
                    FROM images AS i
                    WHERE i.creation_id = c.id
                ) OA (nb_path)
        ) AS g
GROUP BY
    nb_path
;

COALESCE()是 {或ISNULL()可以} 用于没有路径的创建存在的情况。 CROSS APPLY不需要这样做。


NB: APPLY运算符是MS SQL Server独有的(在撰写本文时)

我理解类似的功能是(或将会)通过

CROSS JOIN LINEAL

,这在Oracle 12c中出现

答案 1 :(得分:1)

如果我首先计算每次创作的path个数,然后将结果作为表格分组,那么它是有效的:

select nb_path, COUNT(*) as nb_creations
from (
    select c.id,
    (
        select count(distinct [path])
        from images as i
        where i.creation_id = c.id
    ) as nb_path
    from creations as c
) as g
group by nb_path

答案 2 :(得分:-2)

select cnt nb_paths, count(cnt) nb_creations from (
select count(distinct i.path) cnt from 
creations c join images i
on c.id = i.creation_id
group by i.creation_id)A group by cnt

首先按creation_id汇总,然后按计数汇总。