SELECT `a`.`id`, `a`.`ClientName`, b.id as ActivityId, max(b.DueDate)
FROM `clients` as `a`
LEFT JOIN activities b on b.ClientId = a.id
GROUP BY `a`.`id`
如何获得与MAX值对应的行? 这里我得到了正确的Max DueDate但是ActivityId与MAX DueDate行没有对应
链接到sqlfiddle
在这个演示exmaple链接中:这里max DueDate是2017-07-10它的正确。 ActivityId不正确。它显示为1,但它应显示2.请检查屏幕截图
答案 0 :(得分:1)
我们假设这是你的clients
表:
CREATE TABLE clients
(
id INTEGER NOT NULL PRIMARY KEY,
ClientName varchar(100) NOT NULL
) ;
INSERT INTO clients
VALUES
(1, 'Client 1'),
(2, 'Client 2') ;
这是你的activities
CREATE TABLE activities
(
id INTEGER NOT NULL PRIMARY KEY,
ClientId INTEGER NOT NULL REFERENCES client(id),
DueDate DATE NOT NULL
) ;
INSERT INTO activities
VALUES
(1, 1, '2017-01-01'),
(2, 1, '2017-12-31'),
(3, 1, '2017-05-05'),
(4, 2, '2017-01-03'),
(5, 2, '2017-03-04'),
(6, 2, '2017-06-07') ;
(如果使用MySQL / MariaDB:我们确保我们GROUP BY
使用SQL标准,以避免错误。如果使用PostgreSQL,省略它; PostgreSQL GROUP BY
已经遵循SQL标准)
SET sql_mode = 'ONLY_FULL_GROUP_BY' ;
我们首先制作一个简单 GROUP BY
来获取每个MAX(DueDate)
的{{1}}:
ClientId
我们得到:
ClientId | MaxDate -------: | :--------- 1 | 2017-12-31 2 | 2017-06-07
有了这个结果,我们将它包装为子查询(SELECT
ClientId, max(DueDate) AS MaxDate
FROM
activities
GROUP BY
ClientId ;
),并将q0
与JOIN
表包装起来,以检索相应的激活。
我们还activites
与JOIN
一起检索客户数据:
clients
我们得到:
ClientName | ClientId | ActivityId | DueDate :--------- | -------: | ---------: | :--------- Client 1 | 1 | 2 | 2017-12-31 Client 2 | 2 | 6 | 2017-06-07
您可以在 dbfiddle here
查看所有内容注意:根据您的评论SELECT
c.ClientName, q0.ClientId, a.id AS ActivityId, a.DueDate
FROM
(SELECT
ClientId, max(DueDate) AS MaxDate
FROM
activities
GROUP BY
ClientId
) AS q0
JOIN activities a ON a.ClientId = q0.ClientId AND a.DueDate = q0.MaxDate
RIGHT JOIN clients c ON c.id = q0.ClientId
ORDER BY
c.ClientName ;
,如果您需要所有客户,即使他们没有活动。 RIGHT JOIN
只会为提供活动。
注意:这是SQL标准,不仅仅是MySQL或PostgreSQL。
警告:如果两个或更多活动恰好与JOIN
一致,您将获得所有这些活动。
如果发生这种情况并且您只想一个,那么您可以在没有JOIN的情况下解决问题,但使用带有某个Max(DueDate)
的子查询(优先考虑如果有多个你真正想要的那个)和ORDER BY
。
答案 1 :(得分:0)
对于分组,您需要将select语句中的所有列分组为:
SELECT
`a`.`id`,
`a`.`ClientName`,
b.id as ActivityId,
b.DueDate
FROM `clients` as `a`
LEFT JOIN activities b on b.ClientId = a.id
Where b.DueDate in (select max(DueDate) from activities)
GROUP BY `a`.`id`;