统计信息

时间:2015-08-04 09:57:00

标签: sql oracle

因此,我们假设我有两个表,carsengines。每辆车都有一个id列和sold_date列,指的是汽车售出的日期。每个引擎都有car_idtype列,其中第一列是cars表的外键,第二列是引擎的类型名称,可以是任何来自V1至V999。

所以我想得到的是8月1日到8月3日期间的日期列表,其中包括各种类型的引擎和许多销售过的汽车:

sold_date   engine_type      number_of_sold_cards

08.01.2015  V8              6
08.01.2015  V6              8
08.01.2015  V4              9

08.02.2015  V8              15
08.02.2015  V6              0
08.02.2015  V4              5

08.03.2015  V8              4
08.03.2015  V6              6
08.03.2015  V4              0

这个例子假设在这3天内只卖了带发动机的汽车' V8,V6和V4的类型。这意味着如果在此期间(V8,V6,V4,V2,V0)已售出5种类型的发动机,我每个日期需要5行

2 个答案:

答案 0 :(得分:1)

分区外连接到救援!

with       cars as (select 1 id, to_date('01/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 2 id, to_date('01/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 3 id, to_date('02/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 4 id, to_date('03/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 5 id, to_date('01/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 6 id, to_date('01/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 7 id, to_date('03/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 8 id, to_date('03/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 9 id, to_date('02/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 10 id, to_date('02/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 11 id, to_date('02/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 12 id, to_date('04/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 13 id, to_date('04/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 14 id, to_date('04/08/2015', 'dd/mm/yyyy') sold_date from dual union all
                    select 14 id, to_date('04/08/2015', 'dd/mm/yyyy') sold_date from dual),
        engines as (select 1 car_id, 'V8' engine_type from dual union all
                    select 2 car_id, 'V8' engine_type from dual union all
                    select 3 car_id, 'V8' engine_type from dual union all
                    select 4 car_id, 'V8' engine_type from dual union all
                    select 5 car_id, 'V4' engine_type from dual union all
                    select 6 car_id, 'V4' engine_type from dual union all
                    select 7 car_id, 'V4' engine_type from dual union all
                    select 8 car_id, 'V4' engine_type from dual union all
                    select 9 car_id, 'V6' engine_type from dual union all
                    select 10 car_id, 'V6' engine_type from dual union all
                    select 11 car_id, 'V6' engine_type from dual union all
                    select 12 car_id, 'V6' engine_type from dual union all
                    select 13 car_id, 'V2' engine_type from dual union all
                    select 14 car_id, 'V2' engine_type from dual union all
                    select 15 car_id, 'V0' engine_type from dual),
   engine_types as (select distinct engine_type from engines),
            res as (select c.id car_id,
                           e.engine_type,
                           c.sold_date
                    from   engines e
                           inner join cars c on (e.car_id = c.id)),
      final_res as (select et.engine_type,
                           res.sold_date
                    from   engine_types et
                           left outer join res on (et.engine_type = res.engine_type)),
           dates as (select to_date('01/08/2015', 'dd/mm/yyyy') - 1 + level dt -- paramaterise the start date
                     from   dual
                     connect by level <= to_date('03/08/2015', 'dd/mm/yyyy') - to_date('01/08/2015', 'dd/mm/yyyy') + 1 -- paramaterise the start and end dates
                    )
select dts.dt,
       fr.engine_type,
       count(fr.sold_date) cnt
from   dates dts
       left outer join final_res fr partition by (fr.engine_type) on (dts.dt = fr.sold_date)
group by dts.dt,
         fr.engine_type
order by dts.dt,
         fr.engine_type;

DT         ENGINE_TYPE        CNT
---------- ----------- ----------
01/08/2015 V0                   0
01/08/2015 V2                   0
01/08/2015 V4                   2
01/08/2015 V6                   0
01/08/2015 V8                   2
02/08/2015 V0                   0
02/08/2015 V2                   0
02/08/2015 V4                   0
02/08/2015 V6                   3
02/08/2015 V8                   1
03/08/2015 V0                   0
03/08/2015 V2                   0
03/08/2015 V4                   2
03/08/2015 V6                   0
03/08/2015 V8                   1

第一个和第二个子查询(“汽车”和“引擎”)只是模仿你的桌子;您不需要在查询中包含它们。

“engine_types”子查询只是获取引擎表中使用的不同engine_types列表。如果您有其他表列出了可用的engine_types,那么请改用它。

“dates”子查询只是生成给定日期范围之间的日期列表 - 在理想的世界中,开始日期和结束日期将被参数化(假设这是在PL / SQL或其他日期中运行)。 / p>

“res”子查询在汽车和引擎表上进行连接,以获得每个日期销售的引擎类型。

“final_res”子查询外部连接res和engine_types子查询,以便列出每个引擎类型以及sold_date(如果已售出)。

一旦你有了,那么就可以很容易地在final_res子查询上对日期子查询进行分区外连接。

答案 1 :(得分:0)

您需要加入汽车和引擎表。需要按sold_date和engine_type计算已售出的汽车和组:

select c.sold_date
      ,e.engine_type
      ,count(*) as number_of_sold_cars 
from cars c
inner join engines e on c.id = e.car_id
where c.sold_date between date '2015-08-01' and date '2015-08-03'
group by c.sold_date,e.engine_type 
  

更新

使用此查询,您将在所选时间段内销售所有引擎类型。如果在特定日期没有出售此引擎类型,则number_of_sold_cars将为0:

with engine_type as (
select distinct e.engine_type 
from cars c
inner join engines e on c.id = e.car_id
where c.sold_date between date '2015-08-01' and date '2015-08-03'
)
select c.sold_date
      ,t.engine_type
      ,count(*) as number_of_sold_cars 
from cars c
inner join engines e on c.id = e.car_id
left join enginte_type t on t.engine_type = e.engine_type
where c.sold_date between date '2015-08-01' and date '2015-08-03'
group by c.sold_date,t.engine_type