如何返回具有最小和最大列值的行

时间:2019-05-01 18:23:00

标签: sql-server

我在数据仓库中有一个看起来像这样的表:

TicketNbr  Cpn  Start   End
279211      1   CHS     JFK  
295946      1   JFK     TPA  
279211      2   JFK     TPA  
234916      1   JFK     CHS
284916      1   JFK     CHS
279211      3   TPA     JFK
279211      4   JFK     CHS

我想返回TicketNbr = 279211的行,而我只想返回具有最小和最大Cpn值的行。所以我要从这张表中返回

TicketNbr  Cpn  Start   End       
279211      1   CHS     JFK
279211      4   JFK     CHS

我不太精通SQL,所以尝试了

SELECT
TicketNbr,
MIN(Cpn),
Start AS [StartCity],
End AS [EndCity]
FROM TKTExchange AS T
GROUP BY TicketNbr
WHERE TicketNbr = '279211'
LEFT JOIN
    (SELECT  
    MAX(Cpn),
    Start AS [StartCity],
        End AS [EndCity]
    FROM TKTExchange
    GROUP BY TicketNbr) AS GT
ON T.TicketNbr = GT.TicketNbr

但是GROUPBY在这种情况下不起作用。我该怎么做呢?

4 个答案:

答案 0 :(得分:2)

另一种选择是将WITH TIESrow_number()配合使用

示例

Select Top 1 With Ties * 
 From  YourTable
 Where TicketNbr = 279211 
 Order By Row_Number() over (Partition By [TicketNbr] Order by Cpn Desc)
         *Row_Number() over (Partition By [TicketNbr] Order by Cpn Asc) 

返回

TicketNbr   Cpn Start   End
279211      1   CHS     JFK
279211      4   JFK     CHS

dbFiddle

答案 1 :(得分:1)

使用group by TicketNbr,您可以获取所需的最小值和最大值,然后加入表中。如果还有更多行与Cpn相等,则将全部返回:

select t.* from TKTExchange t
inner join (
  select TicketNbr, min(Cpn) mincpn, max(Cpn) maxcpn
  from TKTExchange
  group by TicketNbr
) g on g.TicketNbr = t.TicketNbr and t.Cpn in (g.mincpn, g.maxcpn)

您可以添加以下条件:

where t.TicketNbr = 279211

答案 2 :(得分:1)

使用CTE和窗口函数与其他方法稍有不同:

WITH VTE AS (
    SELECT *,
           MIN(Cpn) OVER (PARTITION BY TicketNbr) AS MinCpn,
           MAX(Cpn) OVER (PARTITION BY TicketNbr) AS MaxCpn
    FROM (VALUES(279211,1,'CHS','JFK'),  
                (295946,1,'JFK','TPA'),  
                (279211,2,'JFK','TPA'),  
                (234916,1,'JFK','CHS'),
                (284916,1,'JFK','CHS'),
                (279211,3,'TPA','JFK'),
                (279211,4,'JFK','CHS')) V(TicketNbr,Cpn,[Start],[End])
    WHERE V.TicketNbr = 279211)
SELECT V.Cpn,
       V.Cpn,
       V.[Start],
       V.[End]
FROM VTE V
WHERE V.Cpn = V.MinCpn
   OR V.Cpn = V.MaxCpn;

答案 3 :(得分:0)

一种选择是选择顶部和底部记录,然后将它们UNION一起合并为一个数据集。如:

SELECT * FROM (SELECT TOP 1
     [TicketNbr]
    ,[Cpn]
    ,[Start]
    ,[End]
FROM [TKTExchange]
WHERE
    [TicketNbr] = '279211'
ORDER BY
    [Cpn] ASC) AS [A]

UNION

SELECT * FROM (SELECT TOP 1
     [TicketNbr]
    ,[Cpn]
    ,[Start]
    ,[End]
FROM [TKTExchange]
WHERE
    [TicketNbr] = '279211'
ORDER BY
    [Cpn] DESC) AS [B]
相关问题