查询扬子江地点的2024年第一季度的清障数据统计——SQL语句分析学习

查询扬子江地点的2024年第一季度的清障数据统计——SQL语句分析学习
Photo by Sunder Muthukumaran / Unsplash

1.查询扬子江地点的2024年第一季度的清障数据统计——SQL语句分析学习

image-20240424214728127

实际在业务场景中使用到的的sql语句如下:

SELECT DISTINCT
	t.f_eventid AS '事件ID',
	DATE ( t.f_createtime ) AS '日期',-- 	t.f_eventid AS '事件ID'
	CONCAT( t.f_vc_roadid, ' ', t.f_vc_roadname ) AS '清障位置',
	CONCAT( 'K', t.f_str_position, '+', t.f_str_mileage ) AS '发现地点',
CASE
		WHEN tc.f_category = 1 THEN
		'轿车' 
		WHEN tc.f_category = 2 THEN
		'客车' 
		WHEN tc.f_category = 3 THEN
		'货车' 
		WHEN tc.f_category = 4 THEN
		'危化品车' ELSE '未识别' 
	END AS '故障车型',
	t.f_createtime AS '发现时间',
	t.f_event_chuli_date AS '通知时间',
	tr.F_RESCUE_DAODA_DATE AS '到达时间',
	tr.F_RESCUE_LICHANG_DATE AS '撤离时间',
	t.f_dt_endtime AS '结束时间',
	TIMESTAMPDIFF( MINUTE, t.f_createtime, t.f_dt_endtime ) AS '处置时长(分钟)',
	'故障救援' AS '救援类型',
	t.f_vc_createname AS '填报人员'
FROM
	KG_ZZDH.t_event t
	RIGHT JOIN KG_ZZDH.t_event_rescue tr ON t.F_EVENTID = tr.F_EVENTID
	RIGHT JOIN KG_ZZDH.t_event_car tc ON t.F_EVENTID = tc.F_EVENTID 
WHERE
	t.f_unitid = 'ff80818159af9032015a12539f900010' -- "扬子江单位id"
	AND YEAR ( t.f_createtime ) = 2024 
	AND MONTH ( t.f_createtime ) IN ( 1, 2, 3 ) 
	AND t.f_createtime IS NOT NULL 
	AND t.f_event_chuli_date IS NOT NULL 
	AND tr.F_RESCUE_DAODA_DATE IS NOT NULL 
	AND tr.F_RESCUE_LICHANG_DATE IS NOT NULL 
	AND t.f_dt_endtime IS NOT NULL 
ORDER BY
	t.f_createtime DESC;

2.SQL语句编写分解解释:

2.1 表的别名命名:

KG_ZZDH.t_event t

2.2 CASE语句映射:

某个表的字段f_category的值的情况分别有1,2,3,4以及空,并且想要把每个数字分别映射到轿车、客车、货车和危化品车,并且想要把这列表头设置为“故障车型”,可以使用case开头,end结尾的句型,并且使用when设置原来表中的情况,然后使用then来表示想要替换的名称,例如把数字1映射为轿车,使用如下:

CASE
		WHEN tc.f_category = 1 THEN
		'轿车' 
		WHEN tc.f_category = 2 THEN
		'客车' 
		WHEN tc.f_category = 3 THEN
		'货车' 
		WHEN tc.f_category = 4 THEN
		'危化品车' ELSE '未识别'
	END AS '故障车型',

2.3 TimeStampdiff函数计算时间相差值

TIMESTAMPDIFF可以计算两个日期中间相差多少秒,多少分钟或者多少小时等,使用方法如下:

TIMESTAMPDIFF( MINUTE, t.f_createtime, t.f_dt_endtime ) AS '处置时长(分钟)',

SQL语句中的TIMESTAMPDIFF函数是用于计算两个时间戳之间的差异的函数。这个函数在不同的数据库系统(如MySQL)中可能有不同的实现,但基本功能是相似的。
TIMESTAMPDIFF函数的基本语法如下:

TIMESTAMPDIFF(unit, timestamp1, timestamp2)
  • unit 是一个字符串,指定了你要计算的时间差单位,比如SECONDMINUTEHOURDAYWEEKMONTHQUARTERYEAR
  • timestamp1timestamp2 是两个时间戳,你可以指定它们的来源字段或者直接使用日期时间字符串。
    在你提供的SQL语句中:
TIMESTAMPDIFF( MINUTE, t.f_createtime, t.f_dt_endtime ) AS '处置时长(分钟)',
  • t.f_createtimet.f_dt_endtime 是表t中的两个字段,分别代表某个事件的开始时间和结束时间。
  • MINUTE 是指定计算的时间单位为分钟。
  • TIMESTAMPDIFF 函数计算f_createtimef_dt_endtime之间的分钟差,并将这个差值作为'处置时长(分钟)'这一列显示在查询结果中。
    例如,如果t.f_createtime 是一个时间戳 '2023-01-01 10:00:00',而t.f_dt_endtime 是 '2023-01-01 10:30:00',那么TIMESTAMPDIFF函数将返回30,表示从开始时间到结束时间总共过去了30分钟。
    这个函数对于需要计算时间长度、持续时间的数据库查询非常有用,比如在项目管理、活动策划或者任何需要跟踪时间跨度的情况中。

2.4 SQL语句右连接保证右边表格所有数据存在:

FROM
	KG_ZZDH.t_event t
	RIGHT JOIN KG_ZZDH.t_event_rescue tr ON t.F_EVENTID = tr.F_EVENTID
	RIGHT JOIN KG_ZZDH.t_event_car tc ON t.F_EVENTID = tc.F_EVENTID 

在这条SQL语句中,使用了两个RIGHT JOIN操作来连接三个不同的表。这些表可能是数据库中与事件、救援和车辆相关的表。下面是对每个部分的详细解释:

  1. FROM KG_ZZDH.t_event t
  • FROM关键字是SQL查询中用来指定要查询的表的部分。
  • KG_ZZDH.t_event是数据库中一个名为t_event的表的完全限定名,其中KG_ZZDH是模式名(schema name),t_event是表名。
  • t是一个别名,用来代表t_event表在查询中的简写方式。使用别名可以让SQL语句更简洁,尤其是在复杂的查询中。
  1. RIGHT JOIN KG_ZZDH.t_event_rescue tr ON t.F_EVENTID = tr.F_EVENTID
  • RIGHT JOIN是一种连接操作,它返回右 表(KG_ZZDH.t_event_rescue)的所有行,即使在左表(KG_ZZDH.t_event)中没有匹配的行。如果左表中有匹配的行,则结果集中也会包含左表的行。
  • KG_ZZDH.t_event_rescue是另一个表的完全限定名,这里假设它包含了与事件相关的救援信息。
  • trKG_ZZDH.t_event_rescue表的别名,用于在查询中简写。
  • ON t.F_EVENTID = tr.F_EVENTID是连接条件,它指定了两个表之间的连接是通过它们共有的F_EVENTID字段来完成的。这意味着每个事件的F_EVENTIDt_event表和t_event_rescue表中是相同的。
  1. RIGHT JOIN KG_ZZDH.t_event_car tc ON t.F_EVENTID = tc.F_EVENTID
  • 这是第二个RIGHT JOIN操作,它将t_event表与t_event_car表连接起来。
  • KG_ZZDH.t_event_car是包含与事件相关的车辆信息的表的完全限定名。
  • tct_event_car表的别名。
  • ON t.F_EVENTID = tc.F_EVENTID是连接条件,与上面的RIGHT JOIN类似,它指定了t_event表和t_event_car表之间的连接是通过它们共有的F_EVENTID字段来完成的。
    综上所述,这个SQL语句使用了两次RIGHT JOIN来将t_event表与t_event_rescue表和t_event_car表连接起来,以便能够从这三个表中检索相关的信息。每个RIGHT JOIN都是基于F_EVENTID字段的值来匹配记录的。这意味着最终的查询结果将包括t_event表中的所有记录,以及t_event_rescuet_event_car表中与t_event表匹配的记录。如果没有匹配的记录,则t_event_rescuet_event_car表的相关部分将为NULL。

2.5 Where条件筛选:

WHERE
	t.f_unitid = 'ff80818159af9032015a12539f900010' -- "扬子江单位id"
	AND YEAR ( t.f_createtime ) = 2024 
	AND MONTH ( t.f_createtime ) IN ( 1, 2, 3 ) 
	AND t.f_createtime IS NOT NULL 
	AND t.f_event_chuli_date IS NOT NULL 
	AND tr.F_RESCUE_DAODA_DATE IS NOT NULL 
	AND tr.F_RESCUE_LICHANG_DATE IS NOT NULL 
	AND t.f_dt_endtime IS NOT NULL

因为我们需要筛选:f_createtime字段为2024年的数据,因此使用year函数,参数为t表的f_createtime字段,值必须等于2024,因此语句写为:YEAR ( t.f_createtime ) = 2024

又因为需要筛选为第一季度的数据,因此我们需要包含1,2,3月份的数据,注意此处使用in关键词表示包含,而不是像筛选年度那样条件是等于,因此语句写为:MONTH ( t.f_createtime ) IN ( 1, 2, 3 )

使用NOT NULL 关键词筛选此值必须有实际的值,不能包含null和空。

	AND t.f_createtime IS NOT NULL 
	AND t.f_event_chuli_date IS NOT NULL 
	AND tr.F_RESCUE_DAODA_DATE IS NOT NULL 
	AND tr.F_RESCUE_LICHANG_DATE IS NOT NULL 
	AND t.f_dt_endtime IS NOT NULL

2.6 group by 与 distinct 去重的区别

GROUP BYDISTINCT 都可以用来去除查询结果中的重复行,但它们的应用场景和功能有所不同。
DISTINCT 关键字用于去除查询结果中的重复行,它作用于所有列。当我们只关心结果集中不同的行时,可以使用 DISTINCT。例如,如果您想从某个表中查询所有不同的城市,可以使用如下查询:

SELECT DISTINCT city FROM table_name;

这个查询将返回所有不同的城市,不包含重复的城市名。
GROUP BY 子句用于将查询结果集中的多行数据根据一个或多个列进行分组,通常与聚合函数(如 COUNT(), SUM(), AVG(), MAX(), MIN() 等)一起使用,以便对每个分组的数据进行汇总。GROUP BY 可以用于更复杂的数据处理,比如您不仅想要去除重复行,还想要对每个独特的分组进行统计或计算。例如,如果您想查询每个城市的不同职位数量,可以使用如下查询:

SELECT city, COUNT(DISTINCT position) FROM table_name GROUP BY city;

这个查询将返回每个城市及其不同的职位数量。
总结一下区别:

  1. DISTINCT 用于去除查询结果中的完全重复的行。
  2. GROUP BY 用于分组数据,并且通常与聚合函数一起使用,用于对每个分组的数据进行汇总。
  3. GROUP BY 可以用于更复杂的数据分析,而 DISTINCT 通常用于简单的去重操作。
  4. GROUP BY 可以与 HAVING 子句一起使用,以过滤分组后的结果,而 DISTINCT 不能与 HAVING 子句直接配合使用。

2.7 group by 与 having 如何联合使用

GROUP BYHAVING 子句通常一起使用,以便对分组后的数据进行条件过滤。下面是它们的基本用法:

2.7.1 GROUP BY

GROUP BY 子句用于将查询结果集中的多行数据根据一个或多个列进行分组。这对于对每个分组的数据进行聚合计算非常有用,如计算每个分组的总和、平均数、最大值、最小值等。

SELECT column_name(s), AGGREGATE_FUNCTION(column_name)
FROM table_name
WHERE condition
GROUP BY column_name(s);

2.7.2 HAVING

HAVING 子句用于对 GROUP BY 生成的分组结果进行条件过滤。它类似于 WHERE 子句,但 WHERE 子句不能与聚合函数一起使用来过滤分组,而 HAVING 可以。

SELECT column_name(s), AGGREGATE_FUNCTION(column_name)
FROM table_name
WHERE condition
GROUP BY column_name(s)
HAVING condition;

这里的 AGGREGATE_FUNCTION() 是指任何聚合函数,如 COUNT(), SUM(), AVG(), MAX(), MIN() 等。

2.7.3 示例语句

假设我们有一个销售数据表 sales,其中包含列 date, region, amount。我们想要找到每个区域的平均销售额,并且只显示平均销售额大于 1000 的区域。

SELECT region, AVG(amount) AS average_sales
FROM sales
GROUP BY region
HAVING AVG(amount) > 1000;

这个查询将首先根据 region 列对数据进行分组,然后计算每个分组的平均销售额,最后使用 HAVING 子句过滤出平均销售额大于 1000 的分组。
请注意,HAVING 子句总是在 GROUP BY 子句之后使用,因为它是对分组结果进行过滤的。如果需要对未分组的原始数据进行过滤,应该使用 WHERE 子句。