在具有优先级的多个列上使用min聚合函数的查询

时间:2016-09-30 21:53:20

标签: sql-server aggregate-functions

我已经在互联网上环顾四周寻找解决这个问题的办法,但似乎找不到我想要的东西。

假设我们有一个看起来像这样的表:

[{
  screeningToolId: 0,
  screeningTool:{
    comm:true,
    dast:true,
    dire:true,
    ort:false,
    pduq:true,
    pmq:false,
    riskAssessment:2
   }, 
   physicalId: 0,
   physical: {
    ....
   },
   labId: 0,
   labs: {
     .... 
   }

}]

我需要一个查询: 1.返回一个独特的名单(不同的功能)
2.每个名字都有最早的日期(分钟功能)
3.与上述两列一致的id。
4.如果日期相同,请使用min(id)作为决定选择哪一行的方法

所以在这种情况下期望的结果看起来像这样..

_____________________________________________________
| id (PK) | name  |  date      | ... other data ... |
-----------------------------------------------------
|    1    |  BOB  | 2016-11-20 |      ....
--------------------------------     
|    3    |  CARL | 2015-09-02 |      ....
--------------------------------
|    4    |  BOB  | 2016-11-18 |      ....
--------------------------------
|    5    |  JON  | 2016-03-03 |      ....
--------------------------------
|    6    |  TIM  | 2016-11-24 |      ....
--------------------------------
|    7    |  TIM  | 2016-11-24 |      ....
--------------------------------
|    8    |  JON  | 2016-05-05 |      ....
--------------------------------

有没有办法在查询中有效地执行此操作而无需创建临时表并使用脚本循环它?

这让我有一半的方式:
选择distinct(名称),min(日期),......其他数据......来自table1


当我将min函数应用于id时虽然它没有按照我需要的方式运行。在BOB的情况下,它将两行混合并返回1以用于' id'和' 2016-11-18'对于日期 - 这是完全不正确的

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

SQL Server 2005及以上支持窗口函数,row_number可能非常有用。这个或类似的东西应该有效。

SELECT
   name
  ,date
  ,id
 from (--  Can't reference the windowing function within it's own select,
       --  so we make it a subquery
       select
          name
         ,date
         ,id
         ,row_number() over (partition by name order by date, id) Ranking
        from Table1
      ) sub
 where Ranking = 1
 order by name

答案 1 :(得分:0)

;WITH cte AS (
    SELECT *
       ,ROW_NUMBER() OVER (PARTITION BY name ORDER BY Date, Id) as RowNum
    FROM
       @Table
)

SELECT *
FROM
    cte
WHERE
    RowNum = 1

所以,如果你认为它略有不同。您希望每个名称具有最早的日期行。因此,如果您在按日期升序排序的名称上创建partitioned ROW_NUMBER(),然后选择ROW_NUMBER() = 1您将获得答案的位置。有一些方法可以使用聚合来完成此操作。如果你想要第一个id,如果Date与Tim的情况相同,你也可以按顺序添加id。