【问题标题】:Value return incorrectly after calculated field计算字段后返回值不正确
【发布时间】:2020-10-21 15:56:13
【问题描述】:
SELECT
    t3.id,
    t3.prod_ID,
    MIN(diff) AS min_time
FROM
    (SELECT
         t1.id,
         (UNIX_TIMESTAMP(t2.time_stamp_2) - UNIX_TIMESTAMP(t1.time_stamp)) AS diff
     FROM 
         production t1
     LEFT JOIN 
         process t2 ON t1.id = t2.id
     HAVING 
         diff >= 0) tx
LEFT JOIN 
    production t3 ON t3.id = tx.id
GROUP BY
    t3.id

运行后返回结果为:

id  prod_ID   min_time
-----------------------
1   2         1200

它应该返回的是

id  prod_ID   min_time
1   9         1200

我最初以为是加入有错误,经过多次加入测试,同样的错误结果。

SQLFiddle

SQLFiddle_2

SQLFiddle_3

SQLFiddle_2 澄清我使用 Group By 是因为我有多个 ID

SQLFiddle_3 进行更多扩展。

在SQLFiddle_3上运行后,返回结果为:

id  prod_ID   min_time
-----------------------
1   2         1200
2   2         960
3   2         360

应该是这样的

id  prod_ID   min_time
-----------------------
1   9         1200
2   2         960
3   3         360

【问题讨论】:

    标签: sql calculated-columns calculated-field sql-calc-found-rows


    【解决方案1】:

    在您的查询中,您仅GROUP BY t3.id,并且您不在t3.prod_ID 上进行聚合,因此返回的值是未定义的。

    我相信你不需要GROUP BY,甚至不需要重新加入production
    试试这个:

    SELECT t1.id, t1.prod_ID,
           (UNIX_TIMESTAMP(t2.time_stamp_2) - UNIX_TIMESTAMP(t1.time_stamp)) AS diff
    FROM production t1 INNER JOIN process t2
    ON t1.id = t2.id 
    AND (t1.id, t1.prod_ID) = (
      SELECT p.id, p.prod_ID
      FROM production p
      WHERE p.id = t2.id AND (UNIX_TIMESTAMP(t2.time_stamp_2) - UNIX_TIMESTAMP(p.time_stamp)) >= 0
      ORDER BY (UNIX_TIMESTAMP(t2.time_stamp_2) - UNIX_TIMESTAMP(p.time_stamp)) LIMIT 1
    )
    

    请参阅demo
    结果:

    > id | prod_ID | diff
    > -: | ------: | ---:
    >  1 |       9 | 1200
    >  2 |       2 |  960
    

    【讨论】:

    • 对不起@forpas,为了澄清,我编辑了我的问题。我不能使用 LIMIT 因为/如果有多个 ID
    • @silver_river 你的 MySql 版本是多少?
    • 对不起,我是个初学者,MySQL 5.6
    • 我还需要在“过滤”计算字段中的负值后找到最小值。
    • 抱歉,有一个问题。我不知道我可以在这个AND (t1.id, t1.prod_ID) 中使用2 列,我以为只能使用这样的AND (t1.id) 之一。你能分享我可以进一步阅读的任何材料吗?老实说,我不知道用谷歌搜索什么。还有一个,我只认为我可以使用AND (t1.id, t1.prod_ID),在过滤的“WHERE”子句之后使用“AND”。我可以进一步阅读任何材料吗?抱歉耽误您的时间。
    【解决方案2】:

    您的查询确实非常错误,您的内部查询本质上是列出时差,但是您将所有这些好的工作都扔掉了,并且不加入或分组 prod_id,所以它本质上只是选择第一个您插入数据库的值。如果您切换插入数据的顺序,因此先插入 prod_id,然后您会得到您想要的结果,但原因是错误的。

    你的内部查询是这样的:

    SELECT
        t1.id,
        t1.prod_id,
        (UNIX_TIMESTAMP(t2.time_stamp_2)-UNIX_TIMESTAMP(t1.time_stamp)) as diff
        FROM production t1
        left JOIN process t2
        ON t1.id = t2.id
       WHERE (UNIX_TIMESTAMP(t2.time_stamp_2)-UNIX_TIMESTAMP(t1.time_stamp)) > 0
    

    如果你运行它,你会看到你想要的值:

    id     prod_id    diff
    1        2        1800
    1        3        1380
    1        9        1200
    

    ...但是您的外部查询对此没有任何作用。

    有很多方法可以做到这一点,这里有一个简单的方法:

    SELECT 
        t1.id,
        t1.prod_id,
        (UNIX_TIMESTAMP(t2.time_stamp_2)-UNIX_TIMESTAMP(t1.time_stamp)) as diff
        FROM production t1
        left JOIN process t2
        ON t1.id = t2.id
       WHERE (UNIX_TIMESTAMP(t2.time_stamp_2)-UNIX_TIMESTAMP(t1.time_stamp)) > 0
       ORDER BY 3
       LIMIT 1
    

    【讨论】:

    • 嗨,汉塞尔先生。我编辑了我的问题,我不能使用 LIMIT 因为(以防万一)有多个 ID
    • Hansell 先生的洞察力很好,但我还需要计算字段中 >0 'filter' 之后的 MIN。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多