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() 函数异常的主要内容,如果未能解决你的问题,请参考以下文章

如何在 oracle sql 中再次使用 MAX 和 MIN 函数获取值?

sql max函数的使用方法有哪些?

SQL MIN() 函数

SQL MIN() 函数

SQL MAX() 函数

SQL MAX() 函数