Mysql 使用带有DISTINCT的JOIN并对一个表进行优先级排序

Mysql 使用带有DISTINCT的JOIN并对一个表进行优先级排序,mysql,Mysql,我正在尝试合并来自两个表的数据。 这两个表都包含来自同一个传感器的数据,比如说一个传感器测量二氧化碳,每10分钟输入一个条目 第一个表包含已验证的数据。我们叫它station1\u。第二个表包含原始数据。让我们称这一站为1\n 虽然原始数据表包含实时数据,但已验证的表仅包含至少1个月前的数据点。验证这些数据并在事后手动控制需要一些时间,这种情况每月只发生一次 我现在要做的是合并这两个表的数据,在网站上显示实时数据。但是,当验证数据可用时,它应该优先考虑该数据点而不是原始数据点 这方面的相关列有:

我正在尝试合并来自两个表的数据。 这两个表都包含来自同一个传感器的数据,比如说一个传感器测量二氧化碳,每10分钟输入一个条目

第一个表包含已验证的数据。我们叫它station1\u。第二个表包含原始数据。让我们称这一站为1\n

虽然原始数据表包含实时数据,但已验证的表仅包含至少1个月前的数据点。验证这些数据并在事后手动控制需要一些时间,这种情况每月只发生一次

我现在要做的是合并这两个表的数据,在网站上显示实时数据。但是,当验证数据可用时,它应该优先考虑该数据点而不是原始数据点

这方面的相关列有:

timed[bigint20]:包含从1.1.1970开始以毫秒为单位的unix时间戳datetime CO2[双倍]:包含测量的CO2浓度,单位为百万分之一ppm 我编写了以下基本SQL:

SELECT 
    *
FROM
    (SELECT 
        timed, CO2, '2' tab
    FROM
        station1_nrt
    WHERE
        TIMED >= 1386932400000
            AND TIMED <= 1386939600000
            AND TIMED NOT IN (SELECT 
                timed
            FROM
                station1_nrt
            WHERE
                CO2 IS NOT NULL
                    AND TIMED >= 1386932400000
                    AND TIMED <= 1386939600000) UNION SELECT 
        timed, CO2, '1' tab
    FROM
        station1_validated
    WHERE
        CO2 IS NOT NULL
            AND TIMED >= 1386932400000
            AND TIMED <= 1386939600000) a
ORDER BY timed
这无法正常工作,因为它仅选择两个表都有条目的数据点。 不过,我想现在就加入,因为这样会快得多。但是,我不知道如何使用一个独特的或类似的连接来对一个表进行优先级排序。有人能帮我解决这个问题或解释一下吗?

您可以加入,然后在字段中使用IFs来选择已验证的值(如果存在)。比如:

SELECT
IFNULL(s1val.timed,s1.timed) AS timed,
IFNULL(s1val.C02,s1.C02) AS C02,
2 AS 2,
IFNULL(s1val.tab,s1.tab) AS tab,
FROM 
station1_nrt s1
LEFT JOIN station1_validated s1val ON (s1.TIMED = s1val.TIMED)
WHERE
-- Any necessary where clauses
MySQL有一个假设,这可能对你有用。不过,您必须选择特定的列,但可以通过编程方式构建查询

SELECT
    IF(DATE_SUB(NOW(), INTERVAL 1 MONTH) < FROM_UNIXTIME(nrt.TIMED),
        val.value,
        nrt.value
    ) AS value
    -- Similar for other values
FROM
    station1_nrt AS nrt
    JOIN station1_validated AS val USING(id)
ORDER BY TIMED

请注意,USINGid是一个占位符。大概有一些索引列可以连接这两个表。

您没有提到station1中是否存在station1中不存在的记录,因此我使用完全连接。如果station1\u验证中的所有行都存在于station1\u nrt中,则可以改用左联接

像这样的

SELECT IFNULL(n.timed,v.timed) as timed,
       CASE WHEN v.timed IS NOT NULL THEN v.CO2 ELSE n.CO2 END as CO2,
       CASE WHEN v.timed IS NOT NULL THEN '1' ELSE '2' END as tab

FROM station1_nrt as n
FULL JOIN station1_validated as v ON n.timed=v.timed AND v.CO2 IS NOT NULL
    WHERE
        ( n.TIMED between 1386932400000 AND 1386939600000
          or 
          v.TIMED between 1386932400000 AND 1386939600000
        )
        AND 
        (n.CO2 IS NOT NULL OR v.CO2 IS NOT NULL)

@吉姆,@valex,@ExplosionPills 我设法编写了一个sqlselect,它模拟了一个完整的外部连接,因为MySQL中没有完整的连接,并返回验证数据的值(如果存在)。如果没有可用的验证数据,它将返回原始值

这就是我现在使用的SQL:

SET @StartTime  = 1356998400000;
SET @EndTime    = 1386546000000;

SELECT
    timed,
    IFNULL (mergedData.validatedValue, mergedData.rawValue) as value
FROM
((SELECT 
    from_unixtime(timed / 1000) as timed,
    rawData.NOX as rawValue,
    validatedData.NOX as validatedValue
FROM
    nabelnrt_bas as rawData
    LEFT JOIN nabelvalidated_bas as validatedData using(timed)
WHERE 
    (rawData.timed > @StartTime
    AND rawData.timed < @EndTime)
    OR (validatedData.timed > @StartTime
    AND validatedData.timed < @EndTime)

) UNION (
SELECT 
    from_unixtime(timed / 1000) as timed,
    rawData.NOX as rawValue,
    validatedData.NOX as validatedValue
FROM
    nabelnrt_bas as rawData
    RIGHT JOIN nabelvalidated_bas as validatedData using(timed)
WHERE 
    (rawData.timed > @StartTime
    AND rawData.timed < @EndTime)
    OR (validatedData.timed > @StartTime
    AND validatedData.timed < @EndTime)
)
ORDER BY timed DESC) as mergedData

数据点是否与时间相关?例如,TIMED是否将nrt表中的记录与验证表中的记录相关联?是的,TIMED中的值在两个表上的每个数据点上都是相同的。我刚刚尝试了您的语句。我收到一个错误,它找不到字段“val”。@RononDex抱歉,我忘了给表添加别名。不过,你不应该像我一样跑。你需要弄清楚它在做什么,这样你才能做出必要的改变。我知道我必须调整它。实际上,我的表有不同的名称。让我试试,我刚试过,结果是0。我认为问题在于,它只选择两个表中的数据点。但是,已验证的数据表仅包含早于1的数据month@RononDex那么你是说从nrt中删除了一个月前的数据?我收到了一条错误消息,函数IFNULL上的参数计数无效:IFNULLs1val.timed,s1val.timed,s1。timed@RononDex哎呀。打字错误我用一个很长的SQL实现了这一点,检查我的答案对我来说很好,但是我认为n.CO2不是空的或者v.CO2不是空的应该是,而不是OR。此外,您还可以在ON子句中去掉并且v.CO2不为NULL。另外,别忘了orderby.@valex我用一个相当长的SQL实现了这一点,请检查我的答案