我需要在Group By语句中找到列的最早和最新(Non Null)值。
示例:
鲍勃在某一天有多个购买记录。我需要在当天的一组记录中找到Bob的第一次和最后一次购买。
所以我有三条记录,一条是空值,表示没有购买。
我使用以下查询来检索所有员工记录,其中给定日期内有多个记录。
SELECT nameid,
Min(CONVERT(NVARCHAR(25), mdatetime, 10)) AS Date,
Count(*) AS Duplicates
-- <<<Get Earliest Purchase And Latest Purchase From each group Where Not Null>>>
FROM employee
GROUP BY nameid, CONVERT(NVARCHAR(25), mdatetime, 111)
HAVING Count(*) > 1
如果我只是使用MIN(mDateTime)检索最早的日期,则该值可能为null。我需要最早的非空值和每个分组的最新非空值。
感谢您的指导和耐心。
警告:这是我正在编辑的代码的假设再现。场景,命名约定和完整性缩写为简化和突出问题。
答案 0 :(得分:1)
在所有评论之后,答案是:
考虑这个构建方案:
create table employee (nameid varchar(100), mdatetime datetime, purchase varchar(200))
insert into employee values ('Bob', '2014/01/01 12:00pm', 'books')
insert into employee values ('Bob', '2014/01/01 01:00pm', NULL)
insert into employee values ('Bob', '2014/01/01 02:00pm', 'pencil')
将获得第一次和最后一次无空购买并选择购买字段的查询是:
SELECT A.nameid, A.Date, A.MIN_DATE, B.purchase MIN_PURCHASE, A.MAX_DATE, C.PURCHASE MAX_PURCHASE
FROM (
SELECT nameid,
CONVERT(NVARCHAR(25), mdatetime, 10) AS Date,
Min(case when purchase is null then null else mDateTime end) MIN_DATE,
Max(case when purchase is null then null else mDateTime end) MAX_DATE,
Count(*) AS Duplicates
FROM employee A
GROUP BY nameid, CONVERT(NVARCHAR(25), mdatetime, 10)
HAVING Count(*) > 1
) A
INNER JOIN employee B
on A.nameid = B.nameid
and A.MIN_DATE = B.mdatetime
INNER JOIN employee C
on A.nameid = C.nameid
and A.MAX_DATE = C.mdatetime
答案 1 :(得分:1)
SELECT nameid,
CONVERT(NVARCHAR(25), mdatetime, 10) AS dt,
min(case when purchase is not null then mdatetime else null end) as first_purch,
max(case when purchase is not null then mdatetime else null end) as last_purch
FROM employee
GROUP BY nameid, CONVERT(NVARCHAR(25), mdatetime, 10)
having sum(case when purchase is not null then 1 else 0 end) > 1
如果您还想购买已购买的商品(包括第一个和最后一个),您可以运行以下内容:
with sub as(
SELECT nameid,
CONVERT(NVARCHAR(25), mdatetime, 10) AS dt,
min(case when purchase is not null then mdatetime else null end) as first_purch,
max(case when purchase is not null then mdatetime else null end) as last_purch
FROM employee
GROUP BY nameid, CONVERT(NVARCHAR(25), mdatetime, 10)
having sum(case when purchase is not null then 1 else 0 end) > 1
)
select s.nameid,
s.dt,
s.first_purch,
f.purchase as first_purch_item,
s.last_purch,
l.purchase as last_purch_item
from sub s join employee f on s.nameid = f.nameid and s.first_purch = f.mdatetime
join employee l on s.nameid = l.nameid and s.last_purch = l.mdatetime