你的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對排序進行排序,並以您想要的記錄數限制。這樣做的想法是,它得到的總排名除以排名的記錄最接近整數,希望均勻分佈。然後,這些結果按時間戳排序。
不知道它會那樣高效!
有更多的發揮,與做事情的方式非常不同: -
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獲取每個日期範圍內的平均讀數。
對不起,但「幫我處理我的複雜查詢」問題在這裏被視爲「太本地化以至於無法被允許」。只有一種方法可以使某些工作 - 調試它。 –
順便說一句,選擇一個壞的數據庫設計的每一個第n行的氣味。數據庫中沒有順序,根本沒有第n行。 –
我已經嘗試刪除部件。 –