我想选择产品结束日期仅为2018年的网站。
有些网站的产品有多个结束日期。例如,对于站点A,对于产品P1,将有多个结束日期,2018年,2019年,2020年。我想要一个产品结束日期为2018的网站
┌──────┬───────┬─────────┐ │ site │product│ EndDate │ ├──────┼───────┼─────────┤ │ A │ P1 │ 2018 │ │ A │ P2 │ 2018 │ │ A │ P1 │ 2019 │ │ B │ P2 │ 2018 │ │ B │ P1 │ 2018 │ │ B │ P2 │ 2019 │ │ A │ P1 │ 2018 │ │ C │ P2 │ 2018 │ │ C │ P1 │ 2019 │ │ C │ P2 │ 2020 │ └──────┴───────┴─────────┘
根据样本数据,我需要的结果是:
2nd row, A P2 2018 5th row, B P1 2018
我写的查询没有任何内容,我知道这是错的,但万一如果你想看看:
select * from utk1
where EndDate not in (Select * from utk1 where EndDate = '2018')
AND EndDate not in (Select * from utk1 where EndDate = '2019')
答案 0 :(得分:1)
你的方法没问题。您只需要正确的in
逻辑:
select *
from utk1
where site in (Select site from utk1 where EndDate = '2018') and
site not in (Select site from utk1 where EndDate >= '2019');
注意:我并不相信你将岁月存储为字符串。所以,你应该省去单引号。混合类型是一种不好的做法。 (如果值确实是字符串,请在下面添加单引号。)
如果您想在产品级别使用此功能,请使用exists
:
select u.*
from utk1
where not exists (select 1
from utk1 u2
where u2.site = u.site and u2.product = u.product and
u2.enddate >= 2019
) and
exists (select 1
from utk1 u2
where u2.site = u.site and u2.product = u.product and
u2.enddate = 2018
) ;
但是,我认为更好的方法是聚合:
select site, product
from utk1
group by site, product
having max(enddate) = 2018;
这将为您提供2018年结束的site
/ product
对。根据评论,这似乎是对该问题最合理的解释。
答案 1 :(得分:1)
您的问题不够明确,因为您在2018年要求使用EndDate的产品,并且样本中的EndDate列有多个2018条目,而在期望的结果中,您只选择了两个条目而未提及获取预期输出(或记录模式)。换句话说,你给社区一个难题就可以解决(或者我是怎么看的)。
无论如何,从给定的输出,我想你需要获得2018年内列出的网站产品。
所以,(如果我的分析技能仍然存在),从给定的输出中,第二行和第五行已被选中,因为它们之前的行是在同一年(2018年)。
如果是这种情况,您可能需要考虑LAG()
或LEAD()
函数,它们对您的情况很有用。
您可以使用这些函数添加一些起点和终点,这样可以更容易地进一步过滤。
对于您的示例,我使用了ROW_NUMBER()
函数(为了简单起见)。
输出可能会因实际数据而异,因此您需要检查并确保输出正确,如果您看到一些不正确的数据,那么LAG()或LEAD()将成为您的解决方案。
以下是ROW_NUMBER()
;WITH CTE AS(
SELECT
*,
ROW_NUMBER() OVER(PARTITION BY [site] ORDER BY [site]) AS RN
FROM YourTable
)
SELECT
[site],
product,
YEAR(EndDate)
FROM CTE
WHERE
YEAR(EndDate) = 2018
AND RN = 2
ORDER BY [site]
以下是LAG()
(获取上一条记录)的解决方案
;WITH CTE AS(
SELECT
[site],
product,
EndDate AS StartDate,
LAG(EndDate) OVER(PARTITION BY [site] ORDER BY [site]) AS EndDate
FROM YourTable
)
SELECT
[site],
product,
YEAR(EndDate)
FROM CTE
WHERE
YEAR(StartDate) = 2018
AND YEAR(EndDate) = 2018
ORDER BY [site]
答案 2 :(得分:0)
您可以尝试以下
WITH cte (site, product, enddate)
AS (
SELECT site, product, MAX(enddate)
FROM utk1
GROUP BY site, product
)
SELECT site, product, enddate
FROM cte
WHERE enddate = 2018
修改强>
正在为每个网站和产品组合创建一个/ cte集,其最大结束日期。之后只考虑结束2018年的那些 例如。对于站点B产品P1,最大/最高结束日期是2019,这导致不考虑该行。对于站点B P2,最大结束日期是2018年,因此该行是endresult的一部分。
答案 3 :(得分:0)
如果您想要的产品仅在2018年,而不是其他年份,则需要将计数条件添加为1:
SELECT site, product, MAX(EndDate) AS EndDate
FROM utk1
GROUP BY site, product
HAVING MAX(EndDate) = '2018'
AND COUNT(DISTINCT EndDate) = 1;
注意:从您的问题来看,EndDate
似乎是varchar
。如果这不正确并且是一个数字,请将= '2018'
更改为= 2018
(删除引号)。此答案也假设在2018年之前可能有几年。如果情况并非如此,那么最后一行不是必需的,可以删除。
答案 4 :(得分:0)
你应该尝试这个
Select * from (
SELECT site, product, MAX(enddate) as enddate
FROM utk1
GROUP BY site, product
)a where enddate = '2018'
答案 5 :(得分:-1)
select * from utk1
group by site,product
having max(EndDate) ='2018';