【发布时间】:2022-06-28 00:51:25
【问题描述】:
在尝试使用 GpsGate 服务器的报告系统时,我尝试让我只获得每位用户一天的第一次和最后一次旅行。
系统太晦涩,无法获得任何帮助,但我偶然发现了一个我认为不可能的 SQL 错误,也许如果我明白我可以修复 SQL 的原因,那么报告?!
问题是我收到以下错误:
选择列表中的“DistanceDetailed.UserID”列无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。
问题是:任何地方都没有GROUP BY。
这个错误是怎么发生的?有没有其他不使用GROUP BY子句可以构成分组的东西?
整个 SQL 非常不可读,因为报告系统使用了许多子查询。
请不要真的试图理解整件事的作用,因为它读起来很可怕。我只需要一个提示,这里会发生任何分组:
SELECT
PeriodStart,
PeriodEnd,
ApplicationID,
SamplingStart AS StartTime,
SamplingEnd AS StopTime,
DistanceDetailed.Name
FROM
(
SELECT
CAST('2022-06-23T22:00:00' AS DATETIME) AS PeriodStart,
CAST('2022-06-24T22:00:00' AS DATETIME) AS PeriodEnd,
32 AS ApplicationID,
Users.Username,
Users.Name,
DATEDIFF(
SECOND,
Distance01.SamplingStart,
Distance01.SamplingEnd
) AS Duration,
Distance01.SamplingStart,
Distance01.SamplingEnd,
Distance01.UserID,
Distance01.StartAddress,
Distance01.StopAddress,
Distance01.DistanceGps,
Distance01.DistanceOdo,
Distance01.MaxSpeed,
Distance01.AvgSpeed,
Distance01.FatPointState,
Distance01.Fuel
FROM
(
SELECT
data_time_stamp_start AS 'SamplingStart',
data_time_stamp_end AS 'SamplingEnd',
int_01 AS 'UserID',
txt_01 AS 'StartAddress',
txt_02 AS 'StopAddress',
dbl_01 AS 'DistanceGps',
dbl_02 AS 'DistanceOdo',
dbl_03 AS 'MaxSpeed',
dbl_04 AS 'AvgSpeed',
dbl_05 AS 'Fuel',
txt_03 AS 'FatPointState'
FROM
reportv3_data_store
LEFT JOIN reportv3_data_store_ext01 ON reportv3_data_store.report_data_store_id = reportv3_data_store_ext01.report_data_store_id
WHERE
report_data_provider_id = 1
AND int_01 IN (258, 259)
AND application_id = 32
AND data_time_stamp_start BETWEEN '2022-06-23T22:00:00'
AND '2022-06-24T22:00:00'
AND data_time_stamp_end BETWEEN '2022-06-23T22:00:00'
AND DATEADD(DAY, 1, '2022-06-24T22:00:00')
AND (
true_break = 1
OR (
true_break = 0
AND data_time_stamp_start != data_time_stamp_end
)
)
) AS Distance01
JOIN (
SELECT
DISTINCT u.user_id AS UserID,
u.username as Username,
u.name as Name,
u.description as Description,
u.Surname as Surname,
email as Email,
driver_id as IButton
FROM
users u
JOIN user_groups ug ON u.user_id = ug.user_id
JOIN groups g ON g.group_id = ug.group_id
AND g.application_id = 32
) AS Users ON Users.UserID = Distance01.UserID
WHERE
Distance01.UserID IN (
SELECT
UserID
FROM
(
SELECT
tu.user_id AS UserID,
t.tag_id AS TagID,
t.tag_name AS Name,
t.tag_description AS Description
FROM
tag t
JOIN tag_users tu ON tu.tag_id = t.tag_id
WHERE
bo_type = 'Franson.Directory.UserTagWriter'
AND t.application_id = 32
) AS TagUsers
WHERE
TagUsers.TagID IN (297)
)
AND Distance01.SamplingStart >= '2022-06-23T22:00:00'
AND Distance01.SamplingEnd <= '2022-06-24T22:00:00'
AND Distance01.FatPointState != 'sleep'
) AS DistanceDetailed
JOIN (
SELECT
MIN(SamplingStart) AS StartOfDay,
DistanceDetailed.UserID,
DATEPART(DAY, DATEADD(SECOND, 7200, SamplingStart)) AS DayOfMonth
FROM
(
SELECT
CAST('2022-06-23T22:00:00' AS DATETIME) AS PeriodStart,
CAST('2022-06-24T22:00:00' AS DATETIME) AS PeriodEnd,
32 AS ApplicationID,
Users.Username,
Users.Name,
DATEDIFF(
SECOND,
Distance01.SamplingStart,
Distance01.SamplingEnd
) AS Duration,
Distance01.SamplingStart,
Distance01.SamplingEnd,
Distance01.UserID,
Distance01.StartAddress,
Distance01.StopAddress,
Distance01.DistanceGps,
Distance01.DistanceOdo,
Distance01.MaxSpeed,
Distance01.AvgSpeed,
Distance01.FatPointState,
Distance01.Fuel
FROM
(
SELECT
data_time_stamp_start AS 'SamplingStart',
data_time_stamp_end AS 'SamplingEnd',
int_01 AS 'UserID',
txt_01 AS 'StartAddress',
txt_02 AS 'StopAddress',
dbl_01 AS 'DistanceGps',
dbl_02 AS 'DistanceOdo',
dbl_03 AS 'MaxSpeed',
dbl_04 AS 'AvgSpeed',
dbl_05 AS 'Fuel',
txt_03 AS 'FatPointState'
FROM
reportv3_data_store
LEFT JOIN reportv3_data_store_ext01 ON reportv3_data_store.report_data_store_id = reportv3_data_store_ext01.report_data_store_id
WHERE
report_data_provider_id = 1
AND int_01 IN (
258,
259
)
AND application_id = 32
AND data_time_stamp_start BETWEEN '2022-06-23T22:00:00'
AND '2022-06-24T22:00:00'
AND data_time_stamp_end BETWEEN '2022-06-23T22:00:00'
AND DATEADD(DAY, 1, '2022-06-24T22:00:00')
AND (
true_break = 1
OR (
true_break = 0
AND data_time_stamp_start != data_time_stamp_end
)
)
) AS Distance01
JOIN (
SELECT
DISTINCT u.user_id AS UserID,
u.username as Username,
u.name as Name,
u.description as Description,
u.Surname as Surname,
email as Email,
driver_id as IButton
FROM
users u
JOIN user_groups ug ON u.user_id = ug.user_id
JOIN groups g ON g.group_id = ug.group_id
AND g.application_id = 32
) AS Users ON Users.UserID = Distance01.UserID
WHERE
Distance01.UserID IN (
SELECT
UserID
FROM
(
SELECT
tu.user_id AS UserID,
t.tag_id AS TagID,
t.tag_name AS Name,
t.tag_description AS Description
FROM
tag t
JOIN tag_users tu ON tu.tag_id = t.tag_id
WHERE
bo_type = 'Franson.Directory.UserTagWriter'
AND t.application_id = 32
) AS TagUsers
WHERE
TagUsers.TagID IN (297)
)
AND Distance01.SamplingStart >= '2022-06-23T22:00:00'
AND Distance01.SamplingEnd <= '2022-06-24T22:00:00'
AND Distance01.FatPointState != 'sleep'
) AS DistanceDetailed
) AS StartTag ON StartTag.UserID = DistanceDetailed.UserID
AND DistanceDetailed.FatPointState = 'run'
AND DATEPART(DAY, DATEADD(SECOND, 7200, SamplingStart)) = DATEPART(DAY, DATEADD(SECOND, 7200, StartTag.StartOfDay))
JOIN (
SELECT
MAX(SamplingStart) AS EndOfDay,
DistanceDetailed.UserID,
DATEPART(DAY, DATEADD(SECOND, 7200, SamplingStart)) AS DayOfMonth
FROM
(
SELECT
CAST('2022-06-23T22:00:00' AS DATETIME) AS PeriodStart,
CAST('2022-06-24T22:00:00' AS DATETIME) AS PeriodEnd,
32 AS ApplicationID,
Users.Username,
Users.Name,
DATEDIFF(
SECOND,
Distance01.SamplingStart,
Distance01.SamplingEnd
) AS Duration,
Distance01.SamplingStart,
Distance01.SamplingEnd,
Distance01.UserID,
Distance01.StartAddress,
Distance01.StopAddress,
Distance01.DistanceGps,
Distance01.DistanceOdo,
Distance01.MaxSpeed,
Distance01.AvgSpeed,
Distance01.FatPointState,
Distance01.Fuel
FROM
(
SELECT
data_time_stamp_start AS 'SamplingStart',
data_time_stamp_end AS 'SamplingEnd',
int_01 AS 'UserID',
txt_01 AS 'StartAddress',
txt_02 AS 'StopAddress',
dbl_01 AS 'DistanceGps',
dbl_02 AS 'DistanceOdo',
dbl_03 AS 'MaxSpeed',
dbl_04 AS 'AvgSpeed',
dbl_05 AS 'Fuel',
txt_03 AS 'FatPointState'
FROM
reportv3_data_store
LEFT JOIN reportv3_data_store_ext01 ON reportv3_data_store.report_data_store_id = reportv3_data_store_ext01.report_data_store_id
WHERE
report_data_provider_id = 1
AND int_01 IN (
258,
259
)
AND application_id = 32
AND data_time_stamp_start BETWEEN '2022-06-23T22:00:00'
AND '2022-06-24T22:00:00'
AND data_time_stamp_end BETWEEN '2022-06-23T22:00:00'
AND DATEADD(DAY, 1, '2022-06-24T22:00:00')
AND (
true_break = 1
OR (
true_break = 0
AND data_time_stamp_start != data_time_stamp_end
)
)
) AS Distance01
JOIN (
SELECT
DISTINCT u.user_id AS UserID,
u.username as Username,
u.name as Name,
u.description as Description,
u.Surname as Surname,
email as Email,
driver_id as IButton
FROM
users u
JOIN user_groups ug ON u.user_id = ug.user_id
JOIN groups g ON g.group_id = ug.group_id
AND g.application_id = 32
) AS Users ON Users.UserID = Distance01.UserID
WHERE
Distance01.UserID IN (
SELECT
UserID
FROM
(
SELECT
tu.user_id AS UserID,
t.tag_id AS TagID,
t.tag_name AS Name,
t.tag_description AS Description
FROM
tag t
JOIN tag_users tu ON tu.tag_id = t.tag_id
WHERE
bo_type = 'Franson.Directory.UserTagWriter'
AND t.application_id = 32
) AS TagUsers
WHERE
TagUsers.TagID IN (297)
)
AND Distance01.SamplingStart >= '2022-06-23T22:00:00'
AND Distance01.SamplingEnd <= '2022-06-24T22:00:00'
AND Distance01.FatPointState != 'sleep'
) AS DistanceDetailed
) AS EndeTag ON EndeTag.UserID = DistanceDetailed.UserID
AND DistanceDetailed.FatPointState = 'run'
AND DATEPART(DAY, DATEADD(SECOND, 7200, SamplingStart)) = DATEPART(DAY, DATEADD(SECOND, 7200, EndeTag.EndOfDay))
ORDER BY
DATEPART(DAY, DATEADD(SECOND, 7200, SamplingStart)),
DistanceDetailed.UserID
【问题讨论】:
-
因为你有非窗口聚合函数,并且在同一范围内有非聚合列,你必须有一个
GROUP BY子句。因此,您省略了GROUP BY是缺陷,或者您的其他列应该被聚合,因此您不需要GROUP BY子句.. -
您的 MIN(SamplingStart) 没有分组依据。
-
MAX(SamplingStart) OVER (PARTITION BY DistanceDetails.UserID) AS EndOfDay?? -
请注意,错误消息显示的是“要么...或”,而不是标题中的“和”。在没有
group by的情况下使用聚合函数意味着一种类似于group by 'All' -- *invalid sql的逻辑分组。也就是说,它将所有行折叠成一行。
标签: sql-server group-by