如何从SQL查询的每个唯一结果中提取第一个结果?

时间:2016-03-22 19:34:48

标签: sql sql-server row-number

我试图从每个唯一的TnID记录中提取第一个结果,以便我可以将其拉入另一个数据库。

SELECT DISTINCT [Tenant Name]
        ,CARL_Tenant_Contacts.ID
        ,Carl_current_tenants.TnID
        ,PrId FROM CARL_Tenant_Contacts 
        JOIN CARL_Current_Tenants ON CARL_Current_Tenants.ID = CARL_Tenant_Contacts.TnID
        WHERE [Tenant Name] IS NOT NULL 
        and [Tenant Name] != ''

这是我到目前为止所获得的代码,但它并没有完全符合我的要求。

目前的结果是:

SQL result

(还有更多,这只是一个小例子。)

但我想要的东西将返回每个TnID的名字,例如,来自TnID1我希望Julie Robinson女士,来自TnID2我想要Julia Gregg女士,TnID3先生Andrew Leigh webb等等。

这是可行的还是我尝试不可能?

2 个答案:

答案 0 :(得分:6)

这应该这样做:

;WITH CTE
    AS (SELECT DISTINCT
             [Tenant Name]
            , CARL_Tenant_Contacts.ID
            , Carl_current_tenants.TnID
            , PrId
            , RN = ROW_NUMBER() OVER(PARTITION BY Carl_current_tenants.TnID ORDER BY CARL_Tenant_Contacts.ID)
        FROM   CARL_Tenant_Contacts
             JOIN CARL_Current_Tenants ON CARL_Current_Tenants.ID = CARL_Tenant_Contacts.TnID
        WHERE  [Tenant Name] IS NOT NULL
             AND [Tenant Name] != '')
    SELECT A.[Tenant Name]
        , A.ID
        , A.TnID
        , A.PrId
    FROM   CTE AS A 
    WHERE RN = 1;

修改以便处理DISTINCT:

;WITH A
    AS (SELECT DISTINCT
             [Tenant Name]
            , CARL_Tenant_Contacts.ID
            , Carl_current_tenants.TnID
            , PrId
        FROM   CARL_Tenant_Contacts
             JOIN CARL_Current_Tenants ON CARL_Current_Tenants.ID = CARL_Tenant_Contacts.TnID
        WHERE  [Tenant Name] IS NOT NULL
             AND [Tenant Name] != ''),
    CTE
    AS (SELECT A.[Tenant Name]
            , A.ID
            , A.TnID
            , A.PrId
            , RN = ROW_NUMBER() OVER(PARTITION BY A.TnID ORDER BY A.ID)
        FROM   A)
    SELECT A.[Tenant Name]
        , A.ID
        , A.TnID
        , A.PrId
    FROM   CTE AS A
    WHERE  RN = 1;

答案 1 :(得分:0)

精心设计

由于另一个答案是以“糟糕”的方式实现结果,我会再使用一个派生表。如果您将ROW_NUMBER()函数应用于与DISTINCT子句相同的级别,则它实际上不会执行该DISTINCT。

我认为值得指出,因为如果删除行号限制的WHERE子句,则最终会在输出中出现重复记录。

示例:

select distinct 
  tnid, 
  id, 
  row_number() over (partition by tnid order by id) as rn
from (
  select 1 as tnid, 1 as id 
  union all select 1,7 
  union all select 2,3 
  union all select 2,3 -- duplicate record
  union all select 2,9 
  union all select 1,5 
) foo

结果:

tnid | id | rn
-----+----+----
1    | 1  | 1
1    | 5  | 2
1    | 7  | 3
2    | 3  | 1
2    | 3  | 2 -- duplicate record showing in distinct, because it takes the rn column as well
2    | 9  | 3

原始答案

您需要一个ROW_NUMBER()窗口函数,该函数将枚举从TnID开始的每个ID的行。然后只需使用带有WHERE的{​​{1}}子句将输出限制为这些行:

row_num = 1

我花时间为表分配别名以缩短查询时间。