Mysql 带有子查询的非常复杂的查询不起作用
我有一个表格,里面有一些来自电能表的数值。一台小型计算机通过RS485读取一些寄存器,并将值保存到mysql数据库。那部分很好用。现在我正在开发一个PHP网站,它以图形的形式显示记录的数据。我可以选择一个范围,然后只从所选范围中获取值。该网站不应获得超过1000个值。由于这个原因,我曾经得到一个代码,它只选择第n行,n将根据有多少个值进行计算 我已将我的sql命令置于一个新的位置。我知道我不能在那里工作,因为那里有一些参数。我只是想让你看看我的环境 现在我的问题是:如何使当前查询正常工作/它有什么问题?它有一个联接,因为值必须与另一个表中的因子相乘Mysql 带有子查询的非常复杂的查询不起作用,mysql,mysqli,sqlfiddle,Mysql,Mysqli,Sqlfiddle,我有一个表格,里面有一些来自电能表的数值。一台小型计算机通过RS485读取一些寄存器,并将值保存到mysql数据库。那部分很好用。现在我正在开发一个PHP网站,它以图形的形式显示记录的数据。我可以选择一个范围,然后只从所选范围中获取值。该网站不应获得超过1000个值。由于这个原因,我曾经得到一个代码,它只选择第n行,n将根据有多少个值进行计算 我已将我的sql命令置于一个新的位置。我知道我不能在那里工作,因为那里有一些参数。我只是想让你看看我的环境 现在我的问题是:如何使当前查询正常工作/它有什
DeviceID和Register将由PHP mysqli填写。您的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
这是在这里使用1374473600和1374483600传递的最小和最大时间戳之间使用unix时间戳执行子查询以获取1000个时间戳范围,只是为了给您展示一个示例,然后对realvalues和register执行左联接以查找哪个读取进入哪个范围。然后使用AVG获得每个日期范围内的平均读数。对不起,请帮助我解决复杂的查询问题,因为这些问题过于本地化,此处不允许使用。只有一种方法可以让某些东西工作——调试它。顺便说一句,选择第n行的每一行都有一种糟糕的数据库设计的味道。数据库中没有顺序,也没有第n行。我已经尝试删除部分。这是必要的,因为我无法选择范围内的所有值,我只想得到1000行,这就是为什么我必须选择每一个第n行。我应该放置一些吗?然后设置一些变量两次?这可能会更容易,或者只需执行一个子选择,将这些参数传递给它,然后在此基础上执行联接,可能会更容易。将添加一个示例。是的,这就是您的基本原始SQL所要做的。您根据deviceid匹配的寄存器连接realvalues。使用您的测试数据,设备ID全部匹配,因此返回的是9 x 10=90行。但是WHERE子句只检查realvalues表上的寄存器ID。因此,对于设备id 1和寄存器id 40001,从realvalues返回3行,然后从寄存器返回10行=返回30行。你能把你真正想要的,包括如何计算你想要的英文行,我将从中工作。我将选择所有值到PHP数组中,并根据有多少行只写第n行。大约有4.000.000行。应该行的,对。我有一场戏。问题是每N行都会很奇怪。例如,假设您有1001条记录,希望返回1000条。你不可能只得到每一张N的唱片。我有一个剧本,可能会想出一些东西。我会为它修改我的帖子。