MySQL子选择然后组不起作用

时间:2018-08-16 00:12:42

标签: mysql

我有这样的表结构:

CREATE TABLE `table_a` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `col_a_one` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `table_b` (
  `id` int(11) NOT NULL,
  `table_a_id` int(11) DEFAULT NULL,
  `col_b_one` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_a_idx` (`table_a_id`),
  CONSTRAINT `fk_a` FOREIGN KEY (`table_a_id`) REFERENCES `table_a` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

具有此值:

INSERT INTO table_a VALUES (1, 'First Row');
INSERT INTO table_a VALUES (2, 'Second Row');

INSERT INTO table_b VALUES (1,1,'Jan 2017');
INSERT INTO table_b VALUES (2,1,'Feb 2017');
INSERT INTO table_b VALUES (3,2,'Jun 2018');
INSERT INTO table_b VALUES (4,2,'Jul 2018');
INSERT INTO table_b VALUES (5,1,'Mar 2017');

TABLE:table_a

id, col_a_one
1, First Row
2, Second Row

TABLE:table_b

id, table_a_id, col_b_one
1, 1, Jan 2017
2, 1, Feb 2017
3, 2, Jun 2018
4, 2, Jul 2018
5, 1, Mar 2017

在我的计算机上,如果我执行此查询:

SELECT
    c.*
FROM
(
    SELECT 
        t1.`id` AS 'table_a_id',
        t2.`id` AS 'table_b_id',
        t1.`col_a_one`,
        t2.`col_b_one`,
        DATE_FORMAT(STR_TO_DATE(t2.`col_b_one`, '%b %Y'), "%Y-%m-01") AS 'test_column'
    FROM `table_a` t1
         INNER JOIN `table_b` t2
            ON t1.`id` = t2.`table_a_id`
    ORDER BY
        t1.`id` ASC,
        DATE_FORMAT(STR_TO_DATE(t2.`col_b_one`, '%b %Y'), "%Y-%m-01") DESC
) AS c
GROUP BY
    c.`table_a_id`

它将返回错误的结果:

table_a_id, table_b_id, col_a_one, col_b_one, test_column
1, 1, First Row, Jan 2017, 2017-01-01
2, 3, Second Row, Jun 2018, 2018-06-01

但是,如果我在sqlfiddle中执行:http://sqlfiddle.com/#!9/5a1f0/1的结果与我预期的一样:

table_a_id, table_b_id, col_a_one, col_b_one, test_column
1, 5, First Row, Mar 2017, 2017-03-01
2, 4, Second Row, Jul 2018, 2018-07-01

我正在使用MySQL 5.7,这是我使用的sql_mode:

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

我的MySQL服务器怎么了...?

1 个答案:

答案 0 :(得分:0)

编辑2

根据进一步的评论,这可能是您想要的。它从table_b中为每个table_a行选择与该表中的最新日期相对应的所有值:

SELECT a.id AS table_a_id,
    a.col_a_one,
    DATE_FORMAT(STR_TO_DATE(b1.col_b_one, '%b %Y'), "%b %Y") AS 'latest_date',
    COUNT(b.id) AS 'total_item_b',
    b1.col_b_two
FROM table_a a
JOIN table_b b ON b.table_a_id = a.id
JOIN table_b b1 ON b1.table_a_id = a.id AND
    STR_TO_DATE(b1.`col_b_one`, '%b %Y') = (SELECT MAX(STR_TO_DATE(`col_b_one`, '%b %Y'))
                                            FROM table_b
                                            WHERE table_b.table_a_id = a.id)
GROUP BY a.id

输出:

table_a_id  col_a_one   latest_date     total_item_b  col_b_two
1           First Row   Mar 2017        3             Y
2           Second Row  Jul 2018        2             M

更新了SQLFiddle

修改

根据下面的评论,我认为此查询是您真正想要的:

SELECT a.id AS table_a_id,
    a.col_a_one,
    DATE_FORMAT(MAX(STR_TO_DATE(b.col_b_one, '%b %Y')), "%b %Y") AS 'latest_date',
    COUNT(b.id) AS 'total_item_b'
FROM table_a a
JOIN table_b b ON b.table_a_id = a.id
GROUP BY a.id

这将返回table_b中每一行的table_a中的项目数,以及最新(最新)日期:

table_a_id  col_a_one   latest_date     total_item_b
1           First Row   Mar 2017        3
2           Second Row  Jul 2018        2

更新了SQLFiddle

正如@RaymondNijland指出的那样,您没有正确使用GROUP BY。分组时,未聚合和未分组的列将返回随机值,这就是为什么对于与table_a_id不直接相关的所有内容都得到不同结果的原因。看来您要实现的目标是返回table_a_id的值,该值对于每个col_b_one都具有table_a_id的最大值,您可以使用此查询进行此操作:

SELECT 
    a.`id` AS 'table_a_id',
    b.`id` AS 'table_b_id',
    a.`col_a_one`,
    b.`col_b_one`
FROM `table_a` a
JOIN `table_b` b ON a.`id` = b.`table_a_id` AND
  STR_TO_DATE(b.`col_b_one`, '%b %Y') = (SELECT MAX(STR_TO_DATE(`col_b_one`, '%b %Y'))
                                         FROM table_b
                                         WHERE table_b.table_a_id = a.id)
ORDER BY a.id ASC

输出:

table_a_id  table_b_id  col_a_one   col_b_one
1           5           First Row   Mar 2017
2           4           Second Row  Jul 2018

我已更新您的SQLFiddle进行演示。