请教一个sql(按2个字段分组然后从每组取出最大的一条纪录,再根据一个标记为判断是不是取出该值)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请教一个sql(按2个字段分组然后从每组取出最大的一条纪录,再根据一个标记为判断是不是取出该值)相关的知识,希望对你有一定的参考价值。
比如:比如表 test
字段有:id、number、dept、 date、 flag
1 001 aa 20130201 1
2 001 aa 20120801 0
3 001 bb 20130403 1
4 001 bb 20120404 0
5 001 cc 20120604 0
首先,我需要根据number、dept2个字段来分组,等到如下结果:
id、number、dept、 date、 flag
1 001 aa 20130201 1
3 001 bb 20130403 1
5 001 cc 20120604 0
然后,我以number为纬度,判断flag是否全为1,如果为全为1,则取出最大的时间date,
如果不全为1,则不需要取出时间,给0就行;就拿上面的例子来说,在分组之后falg不全为1了,
则不需要取出时间了,假设全为1,则需要取出最大时间20130403。
求各位帮忙,谢谢!
id INT,
[number] varchar(6),
dept varchar(6),
[date] int,
flag int
);
GO
INSERT INTO #test
SELECT 1, '001', 'aa', 20130201, 1 UNION ALL
SELECT 2, '001', 'aa', 20120801, 0 UNION ALL
SELECT 3, '001', 'bb', 20130403, 1 UNION ALL
SELECT 4, '001', 'bb', 20120404, 0 UNION ALL
SELECT 5, '001', 'cc', 20120604, 0 UNION ALL
SELECT 6, '002', 'aa', 20130201, 1 UNION ALL
SELECT 7, '002', 'aa', 20120801, 0 UNION ALL
SELECT 8, '002', 'bb', 20130403, 1 UNION ALL
SELECT 9, '002', 'bb', 20120404, 0 UNION ALL
SELECT 10,'002', 'cc', 20120604, 1
GO
SELECT
main.*
FROM
#test main
WHERE
NOT EXISTS (
SELECT 1
FROM #test sub
WHERE main.[number] = sub.[number] AND main.[dept] = sub.[dept] AND main.[id] > sub.[id]
);
GO
id number dept date flag
----------- ------ ------ ----------- -----------
1 001 aa 20130201 1
3 001 bb 20130403 1
5 001 cc 20120604 0
6 002 aa 20130201 1
8 002 bb 20130403 1
10 002 cc 20120604 1
(6 行受影响)
With MyCTE AS(
SELECT
main.*
FROM
#test main
WHERE
NOT EXISTS (
SELECT 1
FROM #test sub
WHERE main.[number] = sub.[number] AND main.[dept] = sub.[dept] AND main.[id] > sub.[id]
)
)
SELECT
[number] , MAX([date]) AS date
FROM
MyCTE
GROUP BY
[number]
HAVING
SUM( CASE WHEN flag = 1 THEN 1 ELSE 0 END ) = COUNT(flag);
GO
number date
------ -----------
002 20130403
(1 行受影响)追问
你好,非常感谢你,再请教下,第一个查询
NOT EXISTS ---------------把这个not去掉
main.[id] > sub.[id]-----------------把这个删除掉
这样应该不会出错吧
另外,我需要最后需要返回多一列,就是flag 1或者0;
把不全为1的时间返回0或者null,然后把这些合成一张表,
该如何实现呢,谢谢!
如果在的话,可以现在答复我!
你这个需求变化得真是快啊。
NOT EXISTS ---------------把这个not去掉
main.[id] > sub.[id]-----------------把这个删除掉
这样应该不会出错吧
语法不会抱错, 就是结果会发生变化了, 因为逻辑变化了。
SELECTmain.*
FROM
#test main
WHERE
EXISTS (
SELECT 1
FROM #test sub
WHERE main.[number] = sub.[number] AND main.[dept] = sub.[dept]
);
GO
id number dept date flag
----------- ------ ------ ----------- -----------
1 001 aa 20130201 1
字数限制,这里就省略部分。
10 002 cc 20120604 1
(10 行受影响)
这样一来, 下面那个查询。 对于每一个 number, 因为 flag 都有 0 了。
那么结果一行也没有了。
至于你需要最后需要返回多一列,就是flag 1或者0;
把不全为1的时间返回0或者null
With MyCTE AS(第一步的子查询写在这个位置.
)
SELECT
[number] , MAX([date]) AS date, 1 AS flag
FROM
MyCTE
GROUP BY
[number]
HAVING
SUM( CASE WHEN flag = 1 THEN 1 ELSE 0 END ) = COUNT(flag)
-- 上面是flag全部为1的
UNION ALL
-- 下面是flag不全部为1的
SELECT
[number] , 0 AS date, 0 AS flag
FROM
MyCTE
GROUP BY
[number]
HAVING
SUM( CASE WHEN flag = 1 THEN 1 ELSE 0 END ) < COUNT(flag)本回答被提问者采纳 参考技术B SELECT NUMBER,
DEPT,
CASE
WHEN S.B = S.C AND S.B = 1 THEN
S.A
ELSE
0
END
FROM (SELECT NUMBER, DEPT, MAX(DATE) A, MIN(FLAG) B, MAX(FLAG) C
FROM TEST T
GROUP BY NUMBER, DEPT) S;
id是没有意义的 参考技术C
---sqlserver语法
SELECT A.* INTO #TEMPTABLE FROM test A ,(SELECT NUMBER ,DEPT,MAX(DATE) AS MAXDATE FROM test GROUP BY NUMBER ,DEPT) B WHERE A.NUMBER=B.NUMBER AND A.DEPT=B.DEPT AND A.DATE=B.MAXDATE
IF EXISTS (SELECT 1 FROM #TEMPTABLE WHERE FLAG=0)
BEGIN
SELECT 0
END
IF NOT EXISTS (SELECT 1 FROM #TEMPTABLE WHERE FLAG=0)
BEGIN
SELECT MAX(DATE) FROM #TEMPTABLE
END
MYSQL基础
1.having和group by的区别?
1.having:用于对where和group by查询出来的分组经行过滤,查出满足条件的分组结果。它是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作。
2.group by:对select查询出来的结果集按照某个字段或者表达式进行分组,获得一组组的集合,然后从每组中取出一个指定字段或者表达式的值。 在说group by的时候,我们还需要了解聚合函数,聚合函数是SQL语言中一种特殊的函数。
关于聚合索引、group by与having的使用:https://blog.csdn.net/intmainhhh/article/details/80777582
扩展资料:
group by,where,having 是数据库查询中最常用的几个关键字。在工作中,时常用到,当一个语句中同时含有where、group by 、having及聚集函数时,执行顺序如下:
执行where子句查找符合条件的数据;使用group by 子句对数据进行分组;对group by 子句形成的组运行聚集函数计算每一组的值;最后用having 子句去掉不符合条件的组。需要注意的是,having 子句中的每一个元素也必须出现在select列表中。有些数据库例外,如oracle。
---恢复内容结束---
以上是关于请教一个sql(按2个字段分组然后从每组取出最大的一条纪录,再根据一个标记为判断是不是取出该值)的主要内容,如果未能解决你的问题,请参考以下文章