我对SQL Server有一个疑问。如何获得哪个产品名称的价格逐年上涨。 下表中的苹果产品价格逐年增加,因此我需要该记录 如果某产品一年的价格高而另一年的价格下降,则无需获取该记录 如果任何产品的一年价格为10,而下一年的价格必须比上一个价格高,则该记录需要显示
CREATE TABLE [dbo].[product](
[pid] [int] NULL,
[price] [money] NULL,
[year] [int] NULL
);
CREATE TABLE [dbo].[productdetails](
[pid] [int] NULL,
[pname] [varchar](50) NULL
);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (1, 10.0000, 2010);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (1, 9.0000, 2011);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (1, 13.0000, 2012);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (2, 30.0000, 2010);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (2, 20.0000, 2011);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (2, 19.0000, 2012);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (3, 8.0000, 2010);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (3, 10.0000, 2011);
INSERT [dbo].[product] ([pid], [price], [year]) VALUES (3, 15.0000, 2012);
INSERT [dbo].[productdetails] ([pid], [pname]) VALUES (1, N'lg');
INSERT [dbo].[productdetails] ([pid], [pname]) VALUES (2, N'samsung');
INSERT [dbo].[productdetails] ([pid], [pname]) VALUES (3, N'apple');
INSERT [dbo].[productdetails] ([pid], [pname]) VALUES (4, N'mi');
基于上面的数据,我希望输出如下
+--------------+
| Productname |
+--------------+
| Apple |
+--------------+
我尝试如下
SELECT *
FROM product p
JOIN product pd
ON p.pid = pd.pid
AND p.year = pd.year + 1
AND p.price >= pd.price
能否请您告诉我如何编写查询以在SQL Server中实现此任务
答案 0 :(得分:1)
不存在:
select distinct pd.pname [Product Name]
from [dbo].[productdetails] pd inner join [dbo].[product] p
on p.pid = pd.pid
where not exists (
select 1 from product t
where t.pid = pd.pid and
t.price <= (select price from product where pid = t.pid and year = t.year - 1)
)
请参见demo。
结果:
> | Product Name |
> | :------------ |
> | apple |
如果没有每年的价格,但您想将该条件应用于上一个存储的年份,则使用以下方法:
select distinct pd.pname [Product Name]
from [dbo].[productdetails] pd inner join [dbo].[product] p
on p.pid = pd.pid
where not exists (
select 1 from product t
where t.pid = pd.pid and
t.price <= (select max(price) from product where pid = t.pid and year < t.year)
)
请参见demo。
答案 1 :(得分:1)
使用LAG()
= HAVING
的{{1}}和COUNT
,可以得到预期的结果。
查询是动态的,无需对年份或出现次数进行硬编码。
SUM
输出:
SELECT Q.pname AS ProductName
FROM (
SELECT PD.PID, PD.pname,
CASE WHEN COALESCE(
LAG(PR.price) OVER (PARTITION BY PD.PID ORDER BY PR.[year])
, PR.price) <= PR.price THEN 1 ELSE 0 END AS PFlag
FROM product PR
JOIN productdetails PD ON PD.pid = PR.pid
) Q
GROUP BY Q.pname
HAVING COUNT(Q.pname) = SUM(Q.PFlag)
答案 2 :(得分:0)
如果2010、2011和2012年的固定数据始终存在-以下脚本将起作用-
SELECT
PID
FROM [dbo].[product]
GROUP BY PID
HAVING
SUM(CASE WHEN [YEAR] = '2011' THEN PRICE ELSE NULL END)>
SUM(CASE WHEN [YEAR] = '2010' THEN PRICE ELSE NULL END)
AND
SUM(CASE WHEN [YEAR]= '2012' THEN PRICE ELSE NULL END)>
SUM(CASE WHEN [YEAR] = '2011' THEN PRICE ELSE NULL END)
答案 3 :(得分:0)
另一种方法是 (取消注释p1和p0以查看详细信息)
SELECT Distinct
pd.pname as Product
--,p0.*
--,p1.*
FROM gbaluproduct p0
JOIN gbaluproduct p1
ON p0.pid = p1.pid
AND p0.year + 1 = p1.year
AND p0.price < p1.price
Left Join gbaluproductdetails pd
ON p0.pid = pd.pid
结果-
Product
apple
lg
答案 4 :(得分:0)
您可以使用此查询...
即使您每个产品有3条数据记录,此方法也有效。
SELECT Max(productdetails.pname) as ProductName
FROM (SELECT *,
Lag(price, 1) OVER (partition BY pid ORDER BY pid, year ) AS LagPrice,
price AS CurrentPrice,
Lead (price, 1) OVER (partition BY pid ORDER BY pid, year) AS LeadPrice
FROM product) t1
INNER JOIN productdetails ON productdetails.pid = t1.pid
WHERE lagprice IS NOT NULL AND leadprice IS NOT NULL
GROUP BY t1.pid
HAVING Max(CASE WHEN leadprice < currentprice OR lagprice > currentprice THEN 1 ELSE 0 END) < 1
或使用此查询(类似于Arulkumar's query)。
SELECT Max(productdetails.pname) AS ProductName
FROM (SELECT pid,
CASE WHEN Lead(price) OVER (partition BY pid ORDER BY pid, year) >= price THEN 0 ELSE 1
END AS Decreased
FROM product) tmp
INNER JOIN productdetails ON productdetails.pid = tmp.pid
GROUP BY tmp.pid
HAVING Sum(tmp.Decreased) <= 1
表架构和示例数据(添加了更多示例数据)
CREATE TABLE [product](
[pid] [int] NULL,
[price] [money] NULL,
[year] [int] NULL
);
CREATE TABLE [productdetails](
[pid] [int] NULL,
[pname] [varchar](50) NULL
);
INSERT [product] ([pid], [price], [year]) VALUES (1, 10.0000, 2010);
INSERT [product] ([pid], [price], [year]) VALUES (1, 9.0000, 2011);
INSERT [product] ([pid], [price], [year]) VALUES (1, 13.0000, 2012);
INSERT [product] ([pid], [price], [year]) VALUES (2, 30.0000, 2010);
INSERT [product] ([pid], [price], [year]) VALUES (2, 20.0000, 2011);
INSERT [product] ([pid], [price], [year]) VALUES (2, 19.0000, 2012);
INSERT [product] ([pid], [price], [year]) VALUES (3, 8.0000, 2010);
INSERT [product] ([pid], [price], [year]) VALUES (3, 10.0000, 2011);
INSERT [product] ([pid], [price], [year]) VALUES (3, 15.0000, 2012);
INSERT [product] ([pid], [price], [year]) VALUES (3, 20.0000, 2013);
INSERT [product] ([pid], [price], [year]) VALUES (3, 15.0000, 2014);
INSERT [product] ([pid], [price], [year]) VALUES (4, 5.0000, 2010);
INSERT [product] ([pid], [price], [year]) VALUES (4, 10.0000, 2011);
INSERT [product] ([pid], [price], [year]) VALUES (4, 15.0000, 2012);
INSERT [product] ([pid], [price], [year]) VALUES (4, 20.0000, 2013);
INSERT [productdetails] ([pid], [pname]) VALUES (1, N'lg');
INSERT [productdetails] ([pid], [pname]) VALUES (2, N'samsung');
INSERT [productdetails] ([pid], [pname]) VALUES (3, N'apple');
INSERT [productdetails] ([pid], [pname]) VALUES (4, N'mi');
所有数据
+------+----------+------+
| pid | price | year |
+------+----------+------+
| 1 | 10.0000 | 2010 |
| 1 | 9.0000 | 2011 |
| 1 | 13.0000 | 2012 |
| 2 | 30.0000 | 2010 |
| 2 | 20.0000 | 2011 |
| 2 | 19.0000 | 2012 |
| 3 | 8.0000 | 2010 |
| 3 | 10.0000 | 2011 |
| 3 | 15.0000 | 2012 |
| 3 | 20.0000 | 2013 |
| 3 | 15.0000 | 2014 |
| 4 | 5.0000 | 2010 |
| 4 | 10.0000 | 2011 |
| 4 | 15.0000 | 2012 |
| 4 | 20.0000 | 2013 |
+------+----------+------+
查询结果
+-------------+
| ProductName |
+-------------+
| mi |
+-------------+
在线演示:https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=c55c02790f1a6f99bb8d560ab8d3149b
参考
-Arulkumar的查询:https://stackoverflow.com/revisions/55984816/2
答案 5 :(得分:0)
如果我理解正确。您可以利用COUNT()
,LAG()
和SUM()
的优势,然后将逻辑分为:
示例:
SELECT
pname
FROM (
SELECT
p.pid
, p.price
, p.year
, LAG(p.price) OVER(PARTITION BY p.pid ORDER BY p.year) prvPrice
, COUNT(*) OVER(PARTITION BY p.pid) totalPid
, pd.pname
FROM product p
JOIN productdetails pd ON pd.pid = p.pid
) D
GROUP BY
pname
, totalPid
HAVING
SUM(CASE WHEN price > ISNULL(prvPrice,0) THEN 1 ELSE 0 END) = totalPid
因此,苹果在产品表(totalPid)中出现了3次,这意味着我们需要将价格提高3次(每年一次)才能满足您的要求。
您可以根据需要更正条件逻辑,但是为了简单起见,我只想分享这个简单的示例。