【问题标题】:SELECT DISTINCT and CONCAT don't return value correclySELECT DISTINCT 和 CONCAT 不能正确返回值
【发布时间】:2015-06-05 16:43:44
【问题描述】:

我有一个包含以下值的数据库:

CREATE TABLE test (
Id CHAR (50),
Time TIMESTAMP ,
Value CHAR (50)
);

INSERT INTO test VALUES ('JOE', '2015-06-05 15:36:21', "ZONE1");
INSERT INTO test VALUES ('ANNA', '2015-06-05 14:27:35', "ZONE2");
INSERT INTO test VALUES ('JOE','2015-06-05 16:27:36', "ZONE2");
INSERT INTO test VALUES ('ANNA', '2015-06-05 14:45:31',"ZONE1");
INSERT INTO test VALUES ('JOE','2015-06-05 11:12:31', "ZONE4");
INSERT INTO test VALUES ('ANNA', '2015-06-05 10:25:21',"ZONE3");

我喜欢在最后一个 Zone 中找到用户

我尝试使用这条 SQL 指令:

SELECT DISTINCT(Id), MAX(Time) AS Time,
CONCAT('{ "Time":"', DATE_FORMAT(Time, '%Y-%e-%d %h:%i:%s'), '", "ID":"',     CAST(Id AS CHAR), '", "Zone":"', Value, '" }') json
FROM test
GROUP BY Id;

但是,这是回报:

|   Id |                   Time |                                                         json |

|------|------------------------|----------------------------------------------------------------------------------------------|

| ANNA | June, 05 2015 14:45:31 | { "Time":"2015-5-05 02:27:35", "ID":"ANNA", "Zone":"ZONE2" } |

|  JOE | June, 05 2015 16:27:36 |  { "Time":"2015-5-05 03:36:21", "ID":"JOE", "Zone":"ZONE1" } |

我不明白为什么.....它以不同的日期返回,无序 在第三列...

谢谢!

【问题讨论】:

  • 您使用的是哪个 RDBMS / 数据库后端?
  • MYSQL5.1.61。但是,我在其他测试 sql server 中测试了这个测试并得到了相同的结果......
  • 很公平,但它可能会影响您收到的答案。
  • 嗨@Josep 我编辑了关于 AndriyM 建议的答案,对于这类问题有更好的解决方案,所以看看我的编辑。希望我的第一部分答案没有引起任何问题:) GL!

标签: mysql sql select distinct concat


【解决方案1】:

如果我正确理解你的问题,你想做这样的事情:

  SELECT Id, Time,
         CONCAT('{ "Time":"', DATE_FORMAT(Time, '%Y-%e-%d %h:%i:%s'), '", "ID":"', CAST(Id AS CHAR), '", "Zone":"', Value, '" }') json
  FROM (SELECT * 
        FROM test 
        ORDER BY Time DESC) as t
  GROUP BY Id;

这里是SQL Fiddle,看看它是如何工作的......

GL!

P.S.(编辑)你不需要同时使用 DISTINCT 和 GROUP BY 函数,他们做同样的工作......而且他们从组中的第一行中选择值,所以当您想从具有某些值的行中选择值时(例如您的 MAX(time)),您只需将其按顺序放在顶部即可。我在这个子查询中这样做了

(SELECT * 
 FROM test 
 ORDER BY Time DESC) as t

编辑: 再次嗨,关于 Andriy 在评论中的建议,我发现我的第一个答案并不是解决这个问题的最佳解决方案。多亏了 Andriy,我带着更好、更安全的解决方案回来了。

第一个是相关子查询:

SELECT Id, Time,
       CONCAT('{ "Time":"', DATE_FORMAT(Time, '%Y-%e-%d %h:%i:%s'), '", "ID":"', CAST(Id AS CHAR), '", "Zone":"', Value, '" }') json
FROM test t1
WHERE Time = (SELECT MAX(t2.Time)
              FROM test t2
              WHERE t1.id = t2.id);

还有第二个不相关的子查询:

 SELECT t1.Id, t1.Time,
       CONCAT('{ "Time":"', DATE_FORMAT(t1.Time, '%Y-%e-%d %h:%i:%s'), '", "ID":"', CAST(t1.Id AS CHAR), '", "Zone":"', t1.Value, '" }') json
 FROM test t1
 INNER JOIN (SELECT id, MAX(Time) AS Time
             FROM test
             GROUP BY id) AS t2
 ON t1.id = t2.id AND t1.Time = t2.Time;

更多关于这个你可以阅读here,解决这类问题有三种方法我给你写了第一种和第二种方法的查询,让你用左连接玩一下:)

here is SQL Fiddle 看看这个新解决方案是如何工作的。

再次感谢 Andriy M 提出的不明智的建议,即为此使用 Group by 和 Order 子句...

GL!

【讨论】:

  • @Josep 不客气 :) 我很高兴能帮上忙。如果回答对您有帮助,请将其标记为有用
  • @Josep 和 Aleksandar:尽管这是一种已知技术,但手册从未确认它始终有效。在新版本中,行为可能会在没有警告的情况下发生变化,您可能不知道问题出在哪里。
  • @AndriyM ohh tnx 注意我记得我已经以其他方式解决了类似的问题......我知道你的意思我今天没有时间,但我明天会改进我的答案。我知道有一种更好的方法来选择具有最大时间的行而不进行排序而不是分组。再次感谢,我希望这不会给约瑟夫带来太多麻烦 :)
  • @AndriyM 你好,我再次编辑了我的答案,希望你在提出建议时考虑一下……谢谢你:)
  • 感谢您的编辑。我同意您的另外两个建议,因为它们是可靠且一致的。
猜你喜欢
  • 2012-10-07
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-28
相关资源
最近更新 更多