Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 带有子查询的非常复杂的查询不起作用_Mysql_Mysqli_Sqlfiddle - Fatal编程技术网

Mysql 带有子查询的非常复杂的查询不起作用

Mysql 带有子查询的非常复杂的查询不起作用,mysql,mysqli,sqlfiddle,Mysql,Mysqli,Sqlfiddle,我有一个表格,里面有一些来自电能表的数值。一台小型计算机通过RS485读取一些寄存器,并将值保存到mysql数据库。那部分很好用。现在我正在开发一个PHP网站,它以图形的形式显示记录的数据。我可以选择一个范围,然后只从所选范围中获取值。该网站不应获得超过1000个值。由于这个原因,我曾经得到一个代码,它只选择第n行,n将根据有多少个值进行计算 我已将我的sql命令置于一个新的位置。我知道我不能在那里工作,因为那里有一些参数。我只是想让你看看我的环境 现在我的问题是:如何使当前查询正常工作/它有什

我有一个表格,里面有一些来自电能表的数值。一台小型计算机通过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的唱片。我有一个剧本,可能会想出一些东西。我会为它修改我的帖子。