哪个产品销售逐年增加?

时间:2015-10-20 18:54:17

标签: sql oracle

表名是SALES

**PROD_ID**    **YEAR**    **QUANTITY**
  P1             2012         50
  P1             2013         40
  P1             2014         30
  P2             2012         20
  P2             2013         30
  P2             2014         40

输出应该是P2但是如何..?

6 个答案:

答案 0 :(得分:2)

这个怎么样?

select prod_id
from sales
group by prod_id
having (sum(case when year = 2014 then quantity else 0 end) >
        sum(case when year = 2012 then quantity else 0 end)
       );

答案 1 :(得分:2)

使用cte s。

完成此操作的一种稍微复杂的方法

Fiddle with sample data

with diff as ( 
select prod_id ,
case when quantity - nvl(lag(quantity) over(partition by prod_id order by yr),0) > 0 
then 1 else 0 end as df
from sales 
)
,totdiff as (select prod_id, sum(df) totdf from diff group by prod_id)
, totals as (select prod_id, count(*)  cnt from sales group by prod_id)
select d.prod_id
from totdiff d join totals t on t.prod_id = d.prod_id and d.totdf = t.cnt

编辑:正如@ shawnt00在评论中所建议的那样......查询可以简化为

with diff as ( 
select prod_id ,
case when quantity - nvl(lag(quantity) over(partition by prod_id order by yr),0) > 0 
then 1 else 0 end as df
from sales 
)
select prod_id 
from diff 
group by prod_id
having count(*) = sum(df)

答案 2 :(得分:1)

这个问题可以通过两个步骤解决

首先,创建一个列以使用窗口中的滞后函数来计算当年与上一年的销售额差异,然后创建另一列以计算每个PROD_ID的不同年数

第二,使用PROD_ID上的group by子句对数据进行分组,并且仅当所有不同年份的销售额都比去年多时才过滤正确的产品。

数据表-

+---------+------+-------+
| PROD_ID | Year | Sales |
+---------+------+-------+
| P1      | 2012 |    50 |
| P1      | 2013 |    40 |
| P1      | 2014 |    30 |
| P2      | 2012 |    20 |
| P2      | 2013 |    30 |
| P2      | 2014 |    40 |
+---------+------+-------+

查询-

select PROD_ID 
from
    (
    select 
    PROD_ID, sales,
    sales - LAG(sales,1,0) over (partition by PROD_ID order by year asc) as diff,
    count(year) over (partition by PROD_ID) as num_of_years
    from sales
    ) inner_tbl
group by PROD_ID,num_of_years 
having SUM(CASE WHEN diff > 0 THEN 1 ELSE 0 END) = num_of_years

内部查询输出-

+---------+--------+------+--------------+
| PROD_ID |  sales | diff | num_of_years |
+---------+--------+------+--------------+
| P1      |     50 |   50 |            3 |
| P1      |     40 |  -10 |            3 |
| P1      |     30 |  -10 |            3 |
| P2      |     20 |   20 |            3 |
| P2      |     30 |   10 |            3 |
| P2      |     40 |   10 |            3 |
+---------+--------+------+--------------+

最终输出-

+---------+
| PROD_ID |
+---------+
| P2      |
+---------+

答案 3 :(得分:0)

我知道这是一个非常老的问题,发布答案是因为我能够以其他方式解决它。

create table sales (prod_id varchar(10), yr int, quantity int);

insert into sales values ('P1',2012 , 50);
insert into sales values ('P1', 2013, 40);
insert into sales values ('P1', 2014, 30);
insert into sales values ('P2', 2012, 20);
insert into sales values ('P2', 2013, 30);
insert into sales values ('P2', 2014, 40);

with next_year_sales as 
(
select s.prod_id, s.yr, nvl(s1.yr,0) as prev_yr, s.quantity, nvl(s1.quantity,0) as prev_qty from sales s 
left outer join sales s1 on s.prod_id = s1.prod_id and s.yr = s1.yr+1 
),
flag_high_sales as
(
select prod_id, yr, case when prev_yr=0 then 1 when quantity > prev_qty then 1 else 0 end as flag from next_year_sales A
)

select prod_id, min(flag) from flag_high_sales group by prod_id having min(flag)=1;

答案 4 :(得分:0)

我可以想到3种方法:

select a.prod_id from
(
select
prod_id,
CASE WHEN quantity > coalesce(lag(quantity) over(partition by prod_id order by year asc),0) THEN 1 ELSE 0 END as val
FROM
sales
) a
group by a.prod_id
having sum(a.val) = count(prod_id)
;
select a.prod_id from
(
select
prod_id,
quantity - coalesce(lag(quantity) over(partition by prod_id order by year asc),0) as val
FROM
sales
) a
group by a.prod_id
having min(a.val) >=0
;
select a.prod_id from
(
select
prod_id,
year - dense_rank() over(partition by prod_id order by quantity asc) as cal
FROM
sales
) a
group by a.prod_id
having count(distinct cal)=1
;

答案 5 :(得分:0)

以下解决方案使用CTE和OVER CLAUSE-

WITH Sales_CTE
AS (
    SELECT n1.Prod_ID AS n1Prod_ID
        ,COUNT(n1.Year) OVER (PARTITION BY n1.Prod_ID) AS #CountYn1
        ,COUNT(n2.Year) OVER (PARTITION BY n1.Prod_ID) AS #CountYn2
    FROM #Q2 n1
    LEFT JOIN #Q2 n2 ON n1.Prod_ID = n2.Prod_ID
        AND (n1.Year + 1) = n2.Year
        AND n1.Quantity < n2.Quantity
    )
SELECT DISTINCT n1Prod_ID AS [Product ID]
FROM Sales_CTE
WHERE #CountYn1 = (#CountYn2 + 1);