在其中一个连接上选择具有最大值的记录
Selecting a record with max value on one of the joins
我有三个相关的 table 并且需要 select 行显示来自两个 table 的数据基于第三个的值(序列号)。我只对序列号的最大值感兴趣。我已经尝试了在 Whosebug 上建议的多种解决方案,但我仍然无法解决这个问题。
我的 table 的示例代码,所有值的直接 SELECT 可在此处获得:http://sqlfiddle.com/#!6/6b8f7/4/0
我的最终目标是获得这样的 table:
reference groupname serialnum
C:123 Group2 3
C:125 Group1 4
C:126 Group1 1
使用 LIMIT 订购似乎无效。
知道如何解决这个问题吗?
示例数据的 DDL + DML:
CREATE TABLE pm_process
([pm_guid] int, [Descr] varchar(4), [usr_newref] varchar(5))
;
INSERT INTO pm_process
([pm_guid], [Descr], [usr_newref])
VALUES
(11111, 'aaaa', 'C:123'),
(22222, 'bbbb', 'C:125'),
(33333, 'cccc', 'C:126')
;
CREATE TABLE tps_group
([tps_title] varchar(6), [tps_guid] int)
;
INSERT INTO tps_group
([tps_title], [tps_guid])
VALUES
('Group1', 99999),
('Group2', 88888)
;
CREATE TABLE pm_process_assignment
([pm_group_guid] int, [pm_process_guid] int, [pm_serial_number] int)
;
INSERT INTO pm_process_assignment
([pm_group_guid], [pm_process_guid], [pm_serial_number])
VALUES
(99999, 11111, 1),
(99999, 11111, 2),
(88888, 11111, 3),
(88888, 22222, 1),
(99999, 22222, 2),
(88888, 22222, 3),
(99999, 22222, 4),
(99999, 33333, 1)
;
您可以使用 ROW_NUMBER()
在每个 reference
分区中查找具有最大 serialnum
的记录。然后,在外部查询中,select 只有这些记录:
SELECT reference, groupname, serialnum
FROM (
SELECT
pm_process.usr_newref as reference,
pm_assignment_group.tps_title as groupname,
process_assignments.pm_serial_number as serialnum,
ROW_NUMBER() OVER (PARTITION BY pm_process.usr_newref
ORDER BY process_assignments.pm_serial_number DESC) AS rn
FROM
tps_group pm_assignment_group
RIGHT OUTER JOIN pm_process_assignment process_assignments
ON (pm_assignment_group.tps_guid=process_assignments.pm_group_guid)
RIGHT OUTER JOIN pm_process
ON (process_assignments.pm_process_guid=pm_process.pm_guid)
) t
WHERE t.rn = 1
在 SQL 服务器中,最简单的方法可能是使用 APPLY
:
SELECT p.usr_newref as reference,
pag.tps_title as groupname,
pag.pm_serial_number as serialnum
FROM pm_process p OUTER APPLY
(SELECT TOP 1 pa.pm_serial_number, g.tps_title
FROM pm_process_assignment pa JOIN
tps_group g
ON g.tps_guid = pa.pm_group_guid
WHERE pa.pm_process_guid = p.pm_guid
ORDER BY pm_serial_number DESC
) pag
Here 是 SQL Fiddle.
使用 RANK
和 CTE
。它会处理多个 pm_serial_number 具有相同值的情况。
WITH RankTable AS
(
SELECT *, RANK() OVER (
PARTITION BY usr_newref
ORDER BY pm_serial_number DESC) AS R
FROM pm_process
LEFT JOIN pm_process_assignment
ON pm_process_assignment.pm_process_guid = pm_process.pm_guid
LEFT JOIN tps_group
ON tps_group.tps_guid = pm_process_assignment.pm_group_guid
)
SELECT usr_newref, tps_title, pm_serial_number
FROM RankTable
WHERE RankTable.R = 1
我有三个相关的 table 并且需要 select 行显示来自两个 table 的数据基于第三个的值(序列号)。我只对序列号的最大值感兴趣。我已经尝试了在 Whosebug 上建议的多种解决方案,但我仍然无法解决这个问题。
我的 table 的示例代码,所有值的直接 SELECT 可在此处获得:http://sqlfiddle.com/#!6/6b8f7/4/0
我的最终目标是获得这样的 table:
reference groupname serialnum
C:123 Group2 3
C:125 Group1 4
C:126 Group1 1
使用 LIMIT 订购似乎无效。 知道如何解决这个问题吗?
示例数据的 DDL + DML:
CREATE TABLE pm_process
([pm_guid] int, [Descr] varchar(4), [usr_newref] varchar(5))
;
INSERT INTO pm_process
([pm_guid], [Descr], [usr_newref])
VALUES
(11111, 'aaaa', 'C:123'),
(22222, 'bbbb', 'C:125'),
(33333, 'cccc', 'C:126')
;
CREATE TABLE tps_group
([tps_title] varchar(6), [tps_guid] int)
;
INSERT INTO tps_group
([tps_title], [tps_guid])
VALUES
('Group1', 99999),
('Group2', 88888)
;
CREATE TABLE pm_process_assignment
([pm_group_guid] int, [pm_process_guid] int, [pm_serial_number] int)
;
INSERT INTO pm_process_assignment
([pm_group_guid], [pm_process_guid], [pm_serial_number])
VALUES
(99999, 11111, 1),
(99999, 11111, 2),
(88888, 11111, 3),
(88888, 22222, 1),
(99999, 22222, 2),
(88888, 22222, 3),
(99999, 22222, 4),
(99999, 33333, 1)
;
您可以使用 ROW_NUMBER()
在每个 reference
分区中查找具有最大 serialnum
的记录。然后,在外部查询中,select 只有这些记录:
SELECT reference, groupname, serialnum
FROM (
SELECT
pm_process.usr_newref as reference,
pm_assignment_group.tps_title as groupname,
process_assignments.pm_serial_number as serialnum,
ROW_NUMBER() OVER (PARTITION BY pm_process.usr_newref
ORDER BY process_assignments.pm_serial_number DESC) AS rn
FROM
tps_group pm_assignment_group
RIGHT OUTER JOIN pm_process_assignment process_assignments
ON (pm_assignment_group.tps_guid=process_assignments.pm_group_guid)
RIGHT OUTER JOIN pm_process
ON (process_assignments.pm_process_guid=pm_process.pm_guid)
) t
WHERE t.rn = 1
在 SQL 服务器中,最简单的方法可能是使用 APPLY
:
SELECT p.usr_newref as reference,
pag.tps_title as groupname,
pag.pm_serial_number as serialnum
FROM pm_process p OUTER APPLY
(SELECT TOP 1 pa.pm_serial_number, g.tps_title
FROM pm_process_assignment pa JOIN
tps_group g
ON g.tps_guid = pa.pm_group_guid
WHERE pa.pm_process_guid = p.pm_guid
ORDER BY pm_serial_number DESC
) pag
Here 是 SQL Fiddle.
使用 RANK
和 CTE
。它会处理多个 pm_serial_number 具有相同值的情况。
WITH RankTable AS
(
SELECT *, RANK() OVER (
PARTITION BY usr_newref
ORDER BY pm_serial_number DESC) AS R
FROM pm_process
LEFT JOIN pm_process_assignment
ON pm_process_assignment.pm_process_guid = pm_process.pm_guid
LEFT JOIN tps_group
ON tps_group.tps_guid = pm_process_assignment.pm_group_guid
)
SELECT usr_newref, tps_title, pm_serial_number
FROM RankTable
WHERE RankTable.R = 1