更高效的查询MYSQL
我有这样的数据表更高效的查询MYSQL,mysql,datetime,aggregate-functions,Mysql,Datetime,Aggregate Functions,我有这样的数据表 Table 1 Field1 Field2 Field3 00:00:01 Test1 10.0 00:00:01 Test2 7.3 00:00:01 Test3 11.03 00:00:10 Test1 11.0 00:00:10 Test2 17.3 00:00:10 Test3 15.03 01:00:01 Test1 5.0 01:00:01 Test2 4.3 01:00:01 Test3 4.03 01:00:10 Test1 5.0 01:00:10 Te
Table 1
Field1 Field2 Field3
00:00:01 Test1 10.0
00:00:01 Test2 7.3
00:00:01 Test3 11.03
00:00:10 Test1 11.0
00:00:10 Test2 17.3
00:00:10 Test3 15.03
01:00:01 Test1 5.0
01:00:01 Test2 4.3
01:00:01 Test3 4.03
01:00:10 Test1 5.0
01:00:10 Test2 4.3
01:00:10 Test3 4.03
02:00:01 Test1 78.0
02:00:01 Test2 43.3
02:00:01 Test3 19.03
02:00:10 Test1 79.0
02:00:10 Test2 46.3
02:00:10 Test3 14.03
我需要使用下面的查询得到每小时Iam的最大值,但我希望有更高效的时间保存在其他表中
插入表2(时间、类型、编号)
选择字段1、字段2、最大值(字段3)
来自表1
其中字段1类似于“00:%”;
插入表2(时间、类型、编号)
选择字段1、字段2、最大值(字段3)
来自表1
其中字段1类似于“01:%”;
插入表2(时间、类型、编号)
选择字段1、字段2、最大值(字段3)
来自表1
其中字段1类似于“02:%”;
..............
..............
至‘23%’
您可以在不存在的地方使用子句
SELECT Field1 as hr, Field2 as name, Field3 as num
FROM table1 orig
WHERE NOT EXISTS (
SELECT 1
FROM table1 lower
WHERE lower.Field3 > orig.Field3
AND lower.Field1 = orig.Field1
)
因此,基本上你是说“只给我没有其他行具有相同小时和更高数字的行”-假设你有适当的索引,这将是一个非常有效的查询
我还建议您使用比field1、table1等更好的名称
我只剩下了SELECT
语句-将其包装在INSERT
语句中,或者您需要的任何其他语句中。您可以在不存在的地方使用子句
SELECT Field1 as hr, Field2 as name, Field3 as num
FROM table1 orig
WHERE NOT EXISTS (
SELECT 1
FROM table1 lower
WHERE lower.Field3 > orig.Field3
AND lower.Field1 = orig.Field1
)
因此,基本上你是说“只给我没有其他行具有相同小时和更高数字的行”-假设你有适当的索引,这将是一个非常有效的查询
我还建议您使用比field1、table1等更好的名称
我只留下了选择语句-将其包装在插入语句或您需要的任何其他语句中。如果我正确理解您的查询,您希望插入表1
表中每小时出现的字段3
的最大记录。如果是这样的话,那么您可以去掉所有这些insert语句,并用一条insert语句替换它。这条语句使用一个子查询来标识要插入的所有记录,每小时一条
INSERT INTO table2 (Time, TYPE, Number)
SELECT
t1.Field1,
t1.Field2,
t1.Field3
FROM table t1
INNER JOIN
(
SELECT HOUR(Field1) AS max_time, MAX(Field3) AS max_field3
FROM table1
GROUP BY HOUR(Field1)
) t2
ON HOUR(t1.Field1) = t2.max_time AND
t1.Field3 = t2.max_field3
请注意,如果表中有多个日期,只按小时进行聚合可能有点奇怪。相反,您可能希望使用四舍五入到小时顶部的整个日期进行聚合。如果我正确理解您的查询,您希望从表1
中出现的每个小时插入关于字段3
的最大记录。如果是这样的话,那么您可以去掉所有这些insert语句,并用一条insert语句替换它。这条语句使用一个子查询来标识要插入的所有记录,每小时一条
INSERT INTO table2 (Time, TYPE, Number)
SELECT
t1.Field1,
t1.Field2,
t1.Field3
FROM table t1
INNER JOIN
(
SELECT HOUR(Field1) AS max_time, MAX(Field3) AS max_field3
FROM table1
GROUP BY HOUR(Field1)
) t2
ON HOUR(t1.Field1) = t2.max_time AND
t1.Field3 = t2.max_field3
请注意,如果表中有多个日期,只按小时进行聚合可能有点奇怪。相反,您可能希望使用四舍五入到小时顶部的整个日期进行聚合。您需要按TruncToHour(Field)
分组才能做到这一点。诀窍是实现TruncToHour()
,您可以这样做:
TIME(TIME_FORMAT( Field1, '%H:00:00'))
这将获取每行中的时间值,并去掉分和秒,将其替换为零
使用它,您可以得到这个SELECT查询()
然后可以在INSERT语句中使用该结果集
如果您希望从表1中查找与每小时字段3的最大值相对应的详细信息行,则需要使用上述查询作为子查询的嵌套查询。像这样。()
这使用了一种查询模式,该模式逐组查找每个组中的最大值,然后将其连接回原始表以查找最大值所在的详细信息行
SELECT a.Field1, a.Field2, a.Field3
FROM table1 a
JOIN (
SELECT TIME(TIME_FORMAT( Field1, '%H:00:00')) Field1,
Field2, MAX(Field3) Field3
FROM table1
GROUP BY TIME(TIME_FORMAT( Field1, '%H:00:00')), Field2
) b ON TIME(TIME_FORMAT( a.Field1, '%H:00:00')) = b.Field1
AND a.Field2=b.Field2
AND a.Field3=b.Field3
您需要按TruncToHour(字段)
分组才能做到这一点。诀窍是实现TruncToHour()
,您可以这样做:
TIME(TIME_FORMAT( Field1, '%H:00:00'))
这将获取每行中的时间值,并去掉分和秒,将其替换为零
使用它,您可以得到这个SELECT查询()
然后可以在INSERT语句中使用该结果集
如果您希望从表1中查找与每小时字段3的最大值相对应的详细信息行,则需要使用上述查询作为子查询的嵌套查询。像这样。()
这使用了一种查询模式,该模式逐组查找每个组中的最大值,然后将其连接回原始表以查找最大值所在的详细信息行
SELECT a.Field1, a.Field2, a.Field3
FROM table1 a
JOIN (
SELECT TIME(TIME_FORMAT( Field1, '%H:00:00')) Field1,
Field2, MAX(Field3) Field3
FROM table1
GROUP BY TIME(TIME_FORMAT( Field1, '%H:00:00')), Field2
) b ON TIME(TIME_FORMAT( a.Field1, '%H:00:00')) = b.Field1
AND a.Field2=b.Field2
AND a.Field3=b.Field3