所以我在Microsoft SQL 2008中执行以下语句:
SELECT
'UTC' AS timezone,
rel.unique_id AS relay,sns.unique_id AS sensor,
dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) AS time,
SUM(CONVERT(FLOAT,dat.data)) AS total
FROM sensor_data dat
LEFT OUTER JOIN data_package pak ON dat.package_id = pak.id
LEFT OUTER JOIN relays rel ON pak.relay_id = rel.id
LEFT OUTER JOIN sensors sns ON dat.sensor_id = sns.id
LEFT OUTER JOIN sensor_types typ ON sns.sensor_type = typ.id
WHERE typ.name = 'Volume' AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) > ? AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) < ?
GROUP BY rel.unique_id,sns.unique_id, dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0)
ORDER BY time,relay,sensor
如果我使用jTDS / JDBC驱动程序设置参数,如下所示:
Parameter 1: 15
Parameter 2: 15
Parameter 3: 15
Parameter 4: 15
Parameter 5: 2011-10-31 20:00:00
Parameter 6: 15
Parameter 7: 15
Parameter 8: 2011-12-29 19:00:00
Parameter 9: 15
Parameter 10: 15
我收到错误:
Caused by: java.sql.SQLException: Column 'data_package.rtime' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
如果我手动输入15s?空格,查询工作完美,只有日期作为参数。
1)无论如何都要参数化区间值(在这种情况下是15)或者我只需要将其转义并在它成为预备语句之前搜索并替换它(如果这是真的,那么最好的方法是什么Scala / Java中的那个参数)
2)我可以不再重复dateadd(datediff())部分三次吗?我知道我不能在WHERE子句中引用“time”,但是还有其他方法可以指定某个地方以使其更清晰吗?
答案 0 :(得分:5)
您的选择如下:
SELECT dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) AS time,
你的小组:
GROUP BY dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0)
将?
替换为常量,这两个是相同的。
但是使用未命名的参数会引入一个问题。 select版本使用参数1和2,按版本分组使用参数9和10.而SQL Server现在不会将这些参数始终相等。所以它会引发错误。
您可以通过计算子查询中的字段来避免这种情况:
left join
(
select *
, dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) as X
from data_package
) as pak
on dat.package_id = pak.id
您现在可以在查询的其他部分引用pak.X
,例如:
group by
pak.X
答案 1 :(得分:0)
Andomar说问题是使用GROUP BY中的参数是正确的,但我相信他的解决方案可能过于复杂。我想,更容易写:
SELECT
'UTC' AS timezone,
rel.unique_id AS relay,sns.unique_id AS sensor,
dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) AS time,
SUM(CONVERT(FLOAT,dat.data)) AS total
FROM sensor_data dat
LEFT OUTER JOIN data_package pak ON dat.package_id = pak.id
LEFT OUTER JOIN relays rel ON pak.relay_id = rel.id
LEFT OUTER JOIN sensors sns ON dat.sensor_id = sns.id
LEFT OUTER JOIN sensor_types typ ON sns.sensor_type = typ.id
WHERE typ.name = 'Volume' AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) > ? AND dateadd(MINUTE, datediff(MINUTE, 0, pak.rtime) / ? * ?, 0) < ?
GROUP BY rel.unique_id,sns.unique_id, time
ORDER BY time,relay,sensor
(另一方面,因为在你的特定情况下,你在WHERE中使用完全相同的表达式,也许子查询会更好。)