你的 SQL 很奇怪。
您似乎有很多不使用的用户变量(@STARTDATE 和@ENDDATE)。您似乎还使用@REGISTER 和@DEVICEID 用户变量来避免必须为这些两次传递参数。
此外,您在几个子查询中初始化这些,但您为每个子查询使用相同的别名。
编辑 - 进一步我的评论。
以下似乎可以满足您的要求,但并未经过真正的测试确定。它仅使用 2 个参数。
SELECT *
FROM
(
SELECT
realvalues.`Value` * register.Factor,
realvalues.`Timestamp`,
@X := @X + 1 AS rank,
Sub1.JumpSize
FROM realvalues
JOIN register
ON register.DeviceID = realvalues.DeviceID
JOIN
(
SELECT DeviceID, Register, (1000 / COUNT(*)) AS JumpSize
FROM realvalues
WHERE realvalues.DeviceID = ?
AND realvalues.Register = ?
GROUP BY DeviceID, Register
) Sub1
ON Sub1.DeviceID = realvalues.DeviceID AND Sub1.Register = realvalues.Register
CROSS JOIN (SELECT @X := 0) t
) a
WHERE rank MOD GREATEST(JumpSize, 1) = 0
编辑
在这里,您可以找到可能的解决方案。
SELECT *
FROM
(
SELECT Register,
`Timestamp`,
Readout,
MOD(NumRecs , rank)
FROM
(
SELECT
realvalues.Register,
realvalues.`Timestamp`,
realvalues.`Value` * register.Factor AS Readout,
@X := @X + 1 AS rank,
Sub1.NumRecs
FROM realvalues
JOIN register
ON register.DeviceID = realvalues.DeviceID
AND register.Register = realvalues.Register
JOIN
(
SELECT DeviceID, Register, COUNT(*) AS NumRecs
FROM realvalues
WHERE realvalues.DeviceID = ?
AND realvalues.Register = ?
GROUP BY DeviceID, Register
) Sub1
ON Sub1.DeviceID = realvalues.DeviceID AND Sub1.Register = realvalues.Register
CROSS JOIN (SELECT @X := 0) t
ORDER BY realvalues.`Timestamp`
) a
ORDER BY MOD(NumRecs , rank)
LIMIT 1000
) b
ORDER BY `Timestamp`
这是获取按时间戳排序的寄存器/设备的所有详细信息以获取排名。然后它按记录总数除以排名的 mod 排序,并为您想要的记录数设置一个 LIMIT。这样做的想法是,它使总记录除以排名的记录最接近整数,希望是均匀分布的。然后按时间戳对结果进行排序。
虽然不确定它会那么有效!
有更多的戏,做事的方式非常不同:-
SELECT register.Register,
DateRanges.RangeStart,
IFNULL(AVG(realvalues.`Value` * register.Factor), 0)
FROM
(
SELECT 1374473600 + (((1374483600 - 1374473600) / 1000) * (units.i + tens.i * 10 + hundreds.i * 100)) AS RangeStart,
1374473600 + (((1374483600 - 1374473600) / 1000) * ( 1 + units.i + tens.i * 10 + hundreds.i * 100)) - 1 AS RangeEnd
FROM (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens
CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) hundreds
) DateRanges
LEFT OUTER JOIN realvalues
ON UNIX_TIMESTAMP(realvalues.`Timestamp`) BETWEEN DateRanges.RangeStart AND DateRanges.RangeEnd AND realvalues.DeviceID = 1 AND realvalues.Register = 40001
LEFT OUTER JOIN register
ON register.DeviceID = realvalues.DeviceID AND register.Register = realvalues.Register
GROUP BY Register, DateRanges.RangeStart
ORDER BY Register, DateRanges.RangeStart
这是做一个子查询,以获取您传递的最小和最大时间戳之间的 1000 个时间戳范围(使用 unix 时间戳)(这里使用 1374473600 和 1374483600 只是为了向您展示一个示例),然后针对真实值进行左连接并注册到找出哪个读数进入哪个范围。然后只需使用 AVG 获取每个日期范围内的平均读数。