这些数据集的内部连接与子查询结果不同

inner join with subquery results differs for these data sets

CREATE TABLE IF NOT EXISTS `wcd` (
  `id` int(6) unsigned NOT NULL,
  `wid` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `wcd` (`id`, `wid`) VALUES
  ('168', '5685'),
  ('167', '5685'),
  ('166', '5685'),
  ('165', '5685'),
  ('164', '5685'),
  ('163', '5685'),
  ('162', '5684'),
  ('161', '5684');

  CREATE TABLE IF NOT EXISTS `cases` (
  `id` int(6) unsigned NOT NULL,
  `wcd_id` int(11) unsigned NOT NULL,
  `reason_id` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `cases` (`id`, `wcd_id`, `reason_id`) VALUES
  ('20', '168', '4'),
  ('19', '168', '1'),
  ('18', '167', '6'),
  ('17', '167', '5'),
  ('16', '166', '4'),
  ('15', '166', '1'),
  ('14', '165', '4'),
  ('13', '165', '1'),
  ('12', '164', '1'),
  ('11', '163', '4'),
  ('10', '162', '1'),
  ('9', '162', '4'),
  ('8', '162', '5'),
  ('7', '161', '5'),
  ('6', '161', '6');

上面两个table和wcd.id有外键关系=cases.wcd_id, 让我们考虑与 wcd.wid 5865 相关的记录。结果应按 reason_id 分组,条件为 max(cases.id)

我使用下面的查询来实现这个并得到了预期的结果。

SELECT d.id, d.wid, c.* FROM wcd d
LEFT JOIN cases c ON c.wcd_id = d.id
inner JOIN (SELECT MAX(id) AS max_id FROM cases GROUP BY reason_id) c2
ON c2.max_id = c.id
WHERE d.wid = 5685;

结果:

id  wid     id  wcd_id  reason_id
168 5685    19  168     1
168 5685    20  168     4
167 5685    17  167     5
167 5685    18  167     6

对于 5684 的相同查询,查询 returns 0 行 尽管有可用数据。但我期待下面的行。

id  wid     id  wcd_id  reason_id
162 5684    10  162     1
162 5684    9   162     4
162 5684    8   162     5
161 5684    6   161     6

查询有什么问题,需要更改什么才能获得上述 5684 的结果。?

here is the sqlfiddle link

您需要回顾 wcd table 到 属性 的相关性,因为您需要每个 [= 具有 "latest" 原因的行的 ID 12=] - 该列在 cases.

中不可用

在 MySQL 8.0 中,我们只会使用 row_number()... 但是您将问题标记为 MySQL 5.6。我发现表达这一点的最简单方法是使用相关子查询:

SELECT d.id, d.wid, c.* 
FROM wcd d
INNER JOIN cases c ON c.wcd_id = d.id
WHERE c.id = (
    SELECT max(c2.id)
    FROM wcd d2
    INNER JOIN cases c2 ON c2.wcd_id = d2.id
    WHERE d2.wid = d.wid AND c2.reason_id = c.reason_id
)
AND d.wid = 5685;

那么你必须使用 MIN 并去掉 Where Clause.because

 ('162', '5684')
  ('161', '5684')

因为

SELECT 
d.id
, d.wid
, 
c.*
FROM 
wcd d
LEFT JOIN 
cases c 
ON c.wcd_id = d.id
inner JOIN (SELECT MIN(id) AS min_id FROM cases GROUP BY reason_id) c2
ON c2.min_id = c.id

http://sqlfiddle.com/#!9/fb4569/26