SQL使用场景问题,久旱盼甘霖

SQL使用场景问题:
现在有表1和表2,如何通过sql进行关联生成表3。比如表2中的【2023-01-02】这条数据,因为比2023-01-01大且比2023-01-03小,所以落在表1的【小类2】区间,所以生成第13行,标红的字段都是动态计算得出的。如果将这种规则使用sql落地?

img

1、MySQL5.7,可使用变量实现

SELECT * FROM t_test04;

img

SELECT * FROM t_test05;

img

实现SQL:

SELECT t1.大类, t1.小类, t1.结束时间, t2.扫描日期, t2.问题数
  FROM ( SELECT 大类, 小类, 结束时间, @rq 开始时间, @rq := date_add( 结束时间, INTERVAL 1 DAY )
           FROM t_test04 a, ( SELECT @rq := CAST( '1970-01-01' AS date ) ) b
          ORDER BY 大类, 小类, 结束时间 ) t1 LEFT JOIN t_test05 t2 ON t1.大类 = t2.大类 AND t2.扫描日期 BETWEEN t1.开始时间 AND t1.结束时间

结果:

img

你数据都放excle表格里了,也知道需要怎么做,可以看下我的这篇文章,自己写出的SQL才有成就感,有问题可以我和探讨:使用Excel表格辅助分析,为复杂问题编写SQL_创意程序员的博客-CSDN博客

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/704405
  • 你也可以参考下这篇文章:肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!
  • 除此之外, 这篇博客: 【SQL开发实战技巧】系列(三十七):数仓报表场景☞从表内始终只有近两年的数据,要求用两列分别显示其中一年的数据聊行转列隐含信息的重要性中的 文章目录 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

  • 以下回答由chatgpt基于相关博客总结生成:

    我可以根据提供的参考资料和问题提供以下解决方案:

    针对问题中的需求,需要使用SQL语句关联两张表并生成目标表,同时还得计算并动态生成某些字段的值。具体来说,可以采取以下步骤:

    1. 根据参考资料段落1中提到的方法,使用子查询和聚合函数的方式增加一列超限状态(或其他需要计算的字段)到表2中。

    2. 使用LEFT JOIN将表1和修改过的表2进行关联,生成目标表3。在LEFT JOIN中需要使用ON关键字进行关联条件的指定,具体可以使用DATE()函数提取日期,再使用BETWEEN关键字进行小类2区间的匹配。

    3. 按需动态计算并填充表3的其他字段。根据问题描述,需要动态计算标记为红色的字段,可以在SELECT语句中使用IF语句和聚合函数实现。具体来说,可以使用IF函数判断条件,然后使用SUM函数计算各条件下值的和,作为标记为红色的字段的值。

    下面是一个可能的SQL语句实现:

    SELECT
        t1.id, t1.name, t2.date, t2.category,
        IF(t2.date BETWEEN '2023-01-01' AND '2023-01-05', SUM(IF(t2.category = '小类1', t2.value, 0)), 0) +
        IF(t2.date BETWEEN '2023-01-06' AND '2023-01-07', SUM(IF(t2.category = '小类2', t2.value, 0)), 0) AS red_column
    FROM table1 AS t1
    LEFT JOIN (
        SELECT date, category, value, CASE
            WHEN date BETWEEN '2023-01-01' AND '2023-01-05' THEN '小类1'
            WHEN date BETWEEN '2023-01-06' AND '2023-01-07' THEN '小类2'
            END AS category_renamed, 
            CASE
            WHEN category_renamed IS NOT NULL THEN 1
            ELSE 0
            END AS over_limit
        FROM table2
    ) AS t2
    ON t1.category2 = t2.category_renamed
    WHERE t2.over_limit = 1
    GROUP BY t1.id, t2.date
    ORDER BY t1.id, t2.date;
    

    解释一下上面的SQL语句:

    • SELECT语句中选择了4个列,其中第4个列是动态计算的标记红色字段。

    • IF函数在选择第4个列时用来判断时间区间并累加相应的值来计算最终的标记红色字段的值。

    • LEFT JOIN连接了表1和修改的表2,同时关联条件指定了表1的category2列和修改后的表2的category_renamed列相同。

    • 子查询和聚合函数的方式增加了列category_renamed和over_limit到表2中,分别是category列的重命名版和超出限制的标记。

    • WHERE语句中筛选出over_limit列为1的行,也就是超出限制的行。

    • GROUP BY语句中使用表1的id和表2的date分组,以便能够计算得到标记红色字段时的累加求和。

    • ORDER BY语句按照id和date升序排列结果。

    需要注意的一些细节:

    • 参考资料中描述了子查询和聚合函数的方式增加列的方法,这里没有再赘述,需要自己理解并应用到具体的情况中。

    • IF函数中通过判断条件选择要累加的值,因为如果直接对所有的值都进行累加会导致值的重复计算。

    • LEFT JOIN中指定了连接条件,因为如果不指定,将可能出现表1和表2中所有行的笛卡尔积。

    • WHERE语句中筛选over_limit列为1的行,因为这是表2中超出限制的行,可以避免表1中的不必要的行和重复的行。

    • GROUP BY语句中使用表1的id和表2的date分组,是为了对同一个id和date下的多个超限行进行累加,得到标记红色字段时的最终值。

    最后,需要根据自己的具体情况进行适当的修改,以上提供的SQL语句只是一个示例,并不能完全适用于所有的情况。如果对于某些语句或语法不熟悉的话,也可以在查询语句中一个一个打印输出中间结果,以帮助自己更好地理解和调试。