表名是SALES
**PROD_ID** **YEAR** **QUANTITY**
P1 2012 50
P1 2013 40
P1 2014 30
P2 2012 20
P2 2013 30
P2 2014 40
输出应该是P2但是如何..?
答案 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。
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);