SQL min() max() 函数异常
Posted
技术标签:
【中文标题】SQL min() max() 函数异常【英文标题】:SQL min() max() function with exception 【发布时间】:2016-06-27 10:04:21 【问题描述】:这是我的简化代码:
SELECT
a.user_id as User_ID,
min(b.a_day) as Date_from,
max(b.a_day) as Date_to,
c.code as ID
FROM a, b, c
WHERE
a_day > (day, -15, getdate())
GROUP BY
a.user_id,
c.code
查询给出以下输出:
User ID date_from date_to id
1234567 2016-06-13 2016-06-13 B
1234567 2016-06-17 2016-06-17 A
12345672016-06-18 2016-06-18 A
1234567 2016-06-19 2016-06-19 A
1234567 2016-06-20 2016-06-20 A
1234567 2016-06-21 2016-06-21 B
我需要这样的东西:
User ID date_from date_to id
1234567 2016-06-13 2016-06-13 B
1234567 2016-06-17 2016-06-20 A
1234567 2016-06-21 2016-06-21 B
当我将 min() 和 max() 函数与 group by 一起使用时,它可以很好地聚合 ID=A 的所有记录,但 ID=B 应该有例外。我必须日复一日地只聚合具有相同 ID 的日期。
有什么想法吗?
提前致谢。
【问题讨论】:
向我们展示您当前拥有的代码,我们应该能够提供帮助。 编辑你的问题并把代码放在那里,cmets 不是最好的地方 已经完成,抱歉。 【参考方案1】:您可以使用以下策略组合这些行:
-
确定新分组的开始位置。
对 (1) 中的标志进行累积和,以识别每个分组。
然后进行聚合。
这看起来像:
select min(date_from) as date_from, max(date_to) as date_to, id
from (select t.*,
sum(isNewGroup) over (partition by id order by date_from) as grp
from (select t.*,
(case when lag(date_to) over (partition by id order by date_from) >= date_from
then 0 else 1
end) as isNewGroup
from t
) t
) t
group by id, grp;
【讨论】:
感谢您的回答。请参阅我附加的代码。我必须从 3 个不同的表中获取这些数据。 @acc24 。 . .使用 CTE。【参考方案2】:这是我获得最小/最大连续日期的解决方案。
尝试在你的 oracle 中运行 SQL。
对你有帮助吗?
WITH TEST_DATA AS (
SELECT TO_DATE('20160613', 'YYYYMMDD') AS DATE_FROM, TO_DATE('20160613', 'YYYYMMDD') AS DATE_TO, 'B' AS ID FROM DUAL
UNION ALL
SELECT TO_DATE('20160617', 'YYYYMMDD') AS DATE_FROM, TO_DATE('20160617', 'YYYYMMDD') AS DATE_TO, 'A' AS ID FROM DUAL
UNION ALL
SELECT TO_DATE('20160618', 'YYYYMMDD') AS DATE_FROM, TO_DATE('20160618', 'YYYYMMDD') AS DATE_TO, 'A' AS ID FROM DUAL
UNION ALL
SELECT TO_DATE('20160619', 'YYYYMMDD') AS DATE_FROM, TO_DATE('20160619', 'YYYYMMDD') AS DATE_TO, 'A' AS ID FROM DUAL
UNION ALL
SELECT TO_DATE('20160620', 'YYYYMMDD') AS DATE_FROM, TO_DATE('20160620', 'YYYYMMDD') AS DATE_TO, 'A' AS ID FROM DUAL
UNION ALL
SELECT TO_DATE('20160621', 'YYYYMMDD') AS DATE_FROM, TO_DATE('20160621', 'YYYYMMDD') AS DATE_TO, 'B' AS ID FROM DUAL
)
SELECT
MIN(ID) AS ID,
MIN(DATE_FROM) AS DATE_FROM,
MAX(DATE_TO) AS DATE_TO
FROM (
SELECT
CONNECT_BY_ROOT(DATE_FROM) || CONNECT_BY_ROOT(ID) AS GROUP_KEY,
ROW_NUMBER() OVER(PARTITION BY ID, DATE_FROM, DATE_TO ORDER BY ID, LEVEL DESC) AS DISTINCT_FLG,
DATE_FROM,
DATE_TO,
ID
FROM
TEST_DATA
WHERE ID = CONNECT_BY_ROOT(ID)
CONNECT BY DATE_FROM = PRIOR DATE_TO + 1
ORDER BY DATE_FROM
)
WHERE
DISTINCT_FLG = 1
GROUP BY
GROUP_KEY
【讨论】:
【参考方案3】:这里是mysql解决方案:
select grp, min(f) f, max(t) t, i
from
(
select x.*
,case when @lastu = i and datediff(f, @lastf)=1 then @gr:=@gr else @gr:=@gr+1 end grp
,@lastu:= i
,@lastf:= f
from
(
select '2016-06-13' f,'2016-06-13' t ,'B' i union all
select '2016-06-17','2016-06-17','A' union all
select '2016-06-18','2016-06-18','A' union all
select '2016-06-19','2016-06-19','A' union all
select '2016-06-20','2016-06-20','A' union all
select '2016-06-21','2016-06-21','B'
order by i, f, t
) x
, (select @gr:=0, @lastu:='', @lastf:='' ) b
) xx
group by grp, i
【讨论】:
问题标记为 Oracle。以上是关于SQL min() max() 函数异常的主要内容,如果未能解决你的问题,请参考以下文章