Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 哪种产品的销售额逐年增长?_Sql_Oracle - Fatal编程技术网

Sql 哪种产品的销售额逐年增长?

Sql 哪种产品的销售额逐年增长?,sql,oracle,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 输出

表名为SALES

**PROD_ID**    **YEAR**    **QUANTITY**
  P1             2012         50
  P1             2013         40
  P1             2014         30
  P2             2012         20
  P2             2013         30
  P2             2014         40
输出应该是P2,但如何…?

这个怎么样

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)
       );
这个怎么样

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)
       );

用ctes实现这一点的一种稍微复杂的方法

编辑:正如@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)

用ctes实现这一点的一种稍微复杂的方法

编辑:正如@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)

我知道这是一个非常古老的问题,因为我能够以不同的方式解决它,所以我会发布答案

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;

我知道这是一个非常古老的问题,因为我能够以不同的方式解决它,所以我会发布答案

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;

我可以想出三种方法:

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,
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)
;

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

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);

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

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);

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

首先,使用windows中的lag函数创建一列以计算本年度销售额与上一年度销售额的差异,然后创建另一列以计算每个产品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
Inner查询输出-

+---------+--------+------+--------------+
| 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      |
+---------+

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

首先,使用windows中的lag函数创建一列以计算本年度销售额与上一年度销售额的差异,然后创建另一列以计算每个产品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
Inner查询输出-

+---------+--------+------+--------------+
| 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      |
+---------+

它必须每年增加还是仅在最终结果中增加?仅在最终结果中,因为如果你检查产品P2的数量,则其逐年增加,因此我的产量应为P2,它必须每年增加还是仅在最终结果中增加?仅在最终结果中,因为如果你检查产品P2的数量,则其逐年增加,因此,我的输出应该是P2,我的输出应该是P2,因为产品P2的销售正在增加,如果您根据您的数据检查我的表数据,您似乎总是将2012年的数据与2014年的数据进行比较。Gordon的答案就是这样的,并且将P1从输出中排除。我想我们不知道你真正想要的是什么。@shawnt00..逐年递增问题是这样说的..所以我认为每一项都应该有所增加year@vkp我倾向于同意,但你确实看到了只有最终结果才重要的评论?是的..我猜op并不确切知道他需要什么,或者他在我的输出中使用了错误的措辞应仅为P2,因为产品P2的销售正在增加,如果您根据您的数据检查我的表格数据,您似乎总是将2012年数据与2014年数据进行比较。Gordon的答案就是这样的,并且将P1从输出中排除。我想我们不知道你真正想要的是什么。@shawnt00..逐年递增问题是这样说的..所以我认为每一项都应该有所增加year@vkp我倾向于同意,但你确实看到了只有最终结果才重要的评论?是的..我猜op并不确切知道他需要什么,或者可能他用了错误的措辞。更清楚吗就说按产品id从diff group获得sumdf=count*?我想知道你是否有理由这样做加入。是的。这将是相同的,事实上少了几行代码。但我更喜欢这样写,以便更好地理解。也包括你的建议。@shawnt00是否更清楚地说,从diff组按prod_id有sumdf=count*?我想知道你是否有理由这样做加入。是的。这将是相同的,事实上少了几行代码。但我更喜欢这样写,以便更好地理解。也包括你的建议。@shawnt00