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

How do I pull the first result from each unique result of an SQL query?

我正在尝试从每个唯一的 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] != ''

这是我目前得到的代码,但它并不完全符合我的要求。

目前结果是:

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

但我想要的东西会 return 每个 TnID 的名字,例如,来自 TnID1 我想要 Ms Julie Robinson,来自 TnID2 我想要 Ms Julia Gregg,TnID3 Mr Andrew Leigh webb 等等.

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

应该这样做:

;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;

不同的阐述

由于另一个答案是以 "bad" 的方式实现了结果,我会选择另一个派生的 table。如果您在与 DISTINCT 子句相同的级别应用 ROW_NUMBER() 函数,它实际上不会执行 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() window 函数来枚举每个 TnID 从最低 ID 开始的行。然后只需使用带有 row_num = 1WHERE 子句将输出限制为仅那些行:

SELECT [Tenant Name], ID, TnID, PrId
FROM (
    SELECT
        *
        , ROW_NUMBER() OVER (PARTITION BY TnID ORDER BY ID) AS row_num
    FROM (
        SELECT DISTINCT 
              [Tenant Name]
            , ctc.ID
            , cct.TnID
            , PrId
        FROM 
            CARL_Tenant_Contacts ctc
            JOIN CARL_Current_Tenants cct ON cct.ID = ctc.TnID
        WHERE 
            [Tenant Name] IS NOT NULL 
            AND [Tenant Name] != ''
        ) foo
    ) bar
WHERE row_num = 1

我花时间为您的 table 分配别名以缩短查询。