SQL选择最大值,然后显示小于最大值的值

时间:2012-03-13 19:16:02

标签: sql sql-server-2008

对于以下代码,我想看看是否有办法选择最高转速。 PATTERN.VERSION列中的数字,然后仅显示低于该值的结果。

列中的日期显示如下:

Version
--------
2012-03-12 rev. 035    
2012-03-12 rev.035    
2012-03-12 rev.017

在这种情况下,我希望查询选择rev.035的最大值,然后只显示较低的值(rev.017)。我尝试使用MAX聚合和一个小于但不能得到正确结果的子查询。

    SELECT DISTINCT "SEM_AGENT"."DELETED"
   ,"PATTERN"."VERSION" 
  ,"PATTERN"."PATTERNDATE"
  ,"SEM_AGENT"."AGENT_VERSION"
  ,"SEM_CLIENT"."COMPUTER_NAME" "Computer Name"
  , "SEM_COMPUTER"."OPERATION_SYSTEM" "Operation System"
  ,dateadd(s,convert(bigint,"SEM_AGENT"."CREATION_TIME")/1000,'01-01-1970 00:00:00') CREATION_DTTM
  , dateadd(s,convert(bigint,"SEM_AGENT"."LAST_UPDATE_TIME")/1000,'01-01-1970 00:00:00') Lastupdatetime
  , DATEADD(s, convert(bigint,LAST_SCAN_TIME)/1000, '01-01-1970 00:00:00')"Last Scan Time"
  , "PATTERN"."PATTERNDATE" "Pattern Date"
  , "SEM_CLIENT"."USER_NAME" "User Name"
  , "V_SEM_COMPUTER"."IP_ADDR1_TEXT" "IP Address"
  , "IDENTITY_MAP"."NAME" "Group Name"
FROM (((("SEM_AGENT" "SEM_AGENT" INNER JOIN "SEM_CLIENT" "SEM_CLIENT" 
  ON (("SEM_AGENT"."COMPUTER_ID"="SEM_CLIENT"."COMPUTER_ID") 
  AND ("SEM_AGENT"."DOMAIN_ID"="SEM_CLIENT"."DOMAIN_ID")) 
  AND ("SEM_AGENT"."GROUP_ID"="SEM_CLIENT"."GROUP_ID")) INNER JOIN "SEM_COMPUTER" "SEM_COMPUTER" 
  ON (("SEM_AGENT"."COMPUTER_ID"="SEM_COMPUTER"."COMPUTER_ID") 
  AND ("SEM_AGENT"."DOMAIN_ID"="SEM_COMPUTER"."DOMAIN_ID")) 
  AND ("SEM_AGENT"."DELETED"="SEM_COMPUTER"."DELETED")) INNER JOIN "PATTERN" "PATTERN" 
  ON "SEM_AGENT"."PATTERN_IDX"="PATTERN"."PATTERN_IDX") INNER JOIN "IDENTITY_MAP" "IDENTITY_MAP" 
  ON "SEM_CLIENT"."GROUP_ID"="IDENTITY_MAP"."ID") INNER JOIN "V_SEM_COMPUTER" "V_SEM_COMPUTER" 
  ON "SEM_COMPUTER"."COMPUTER_ID"="V_SEM_COMPUTER"."COMPUTER_ID" 
  AND "SEM_AGENT"."DELETED"=0


ORDER BY "Computer Name"

SAMPLE ROWS

IP Address  DELETED VERSION PATTERNDATE AGENT_VERSION   Computer Name   Operation System    CREATION_DTTM   Lastupdatetime  Last Scan Time  Pattern Date    User Name   Group Name  ip_address  device_type user_tag
16X.XX.XX.XX    0   2012-03-13 rev. 002 3/13/2012 12:00:00 AM   12.1.671.4971   MD-EISN-1206    Windows XP Professional     11/10/2011 8:25:46 PM   3/13/2012 7:49:25 PM    3/11/2012 1:00:05 PM    3/13/2012 12:00:00 AM   ECOPYSCAN   My Company\AHRQ\eCOPY-machines  16X.XX.XX.XX    Desktop |fisma-mgmt|fisma-all|
16X.XX.XX.XX    0   2012-03-13 rev. 002 3/13/2012 12:00:00 AM   12.1.671.4971   HHS-46801948    Windows XP Professional     11/10/2011 8:25:46 PM   3/13/2012 7:49:25 PM    3/11/2012 12:00:02 PM   3/13/2012 12:00:00 AM   EcopyIOD    My Company\AHRQ\eCOPY-machines  16X.XX.XX.XX    Desktop |workstations|network scanners|fisma-mgmt|desktops|fisma-all|
16X.XX.XX.XX    0   2012-03-13 rev. 002 3/13/2012 12:00:00 AM   12.1.671.4971   HHS-46801937    Windows XP Professional     11/10/2011 8:25:46 PM   3/13/2012 7:49:25 PM    3/11/2012 12:00:03 PM   3/13/2012 12:00:00 AM   tim.erny    My Company\AHRQ\eCOPY-machines  16X.XX.XX.XX    Desktop |network scanners|fisma-mgmt|desktops|fisma-all|

2 个答案:

答案 0 :(得分:0)

使用RANK中的CTE功能,使用ORDER BY按降序对修订号进行排序。然后从CTE中选择RANK值大于1。

请参阅示例here

答案 1 :(得分:0)

首先,答案是:你可以使用RANK函数作为子查询,如上面提到的章节(这里不需要CTE,除了可能很好的东西)

(SELECT PatternID, RANK() OVER (ORDER BY Version DESC) AS Ranking) AS RankTbl
WHERE Ranking > 1

RANK会给相同版本提供相同的排名(听起来像你想要的那样),但是如果你想为每个版本条目提供一个唯一的排名,那么你会想要使用ROW_NUMBER()

但是,这只有在运行某种SUBSTRING时才会起作用,该{{1}}将从日期中选出修订版,以便它可以正确运行订单。但是,创建一个更规范化的数据库将使这更容易(见下文)

其次,一些注意事项:

  • 您不应该在查询的每个部分都需要双引号。它只会降低代码的可读性。如果必须使用描述,则使用方括号[]
  • 如果可以,请从版本中删除修订版本。这将允许您更接近普通数据库,并允许您在不进行任何字符串操作的情况下对版本进行排序

这些只是我对上述内容的看法......