【问题标题】:Select MAX() or Select TOP 1 on Join选择 MAX() 或在加入时选择 TOP 1
【发布时间】:2018-08-01 21:38:47
【问题描述】:

我正在使用以下代码,每个案例只获得一个关联人,使用 MAX Associated Type 获得前 1 个。

关联类型不是 GUID,而是看起来像:

责任方、主治医师等

碰巧责任方是最后一个按字母顺序排列的选项,所以这是一个幸运的解决方法。但是,并非每个案例都有责任方,如果没有责任方,则下一个最重要的相关人员“足够好”,无论如何都会突出显示为数据错误。

结果显示每个关联人(而不是前 1 个),但将所有这些人都显示为责任方,这是不正确的。我在这里做错了什么?

FROM T_LatestIFSP Ltst

LEFT OUTER JOIN ( 
    SELECT
        Clas.ClientCase_ID,
        MAX(Astp.AssociatedType) AS AssociatedType
    FROM
        T_ClientAssociatedPerson Clas
        Inner Join T_AssociatedType Astp
        ON  Clas.AssociatedType_ID = Astp.AssociatedType_ID
    GROUP BY Clas.ClientCase_ID
) AS Astp ON Ltst.ClientCase_ID = Astp.ClientCase_ID


LEFT OUTER JOIN T_ClientAssociatedPerson Clas
    on Clas.ClientCase_ID = Astp.ClientCase_ID


LEFT OUTER JOIN T_AssociatedPerson Aspr
    ON Aspr.AssociatedPerson_ID = Clas.AssociatedPerson_ID

【问题讨论】:

  • 我应该加入 AssociatedPerson_ID 上的后续表,而不是 ClientCase_ID?如果是这样,我如何在 SELECT 语句中包含 AssociatedPerson_ID?
  • 您能提供一些示例数据并期待结果吗?
  • @D-Shih - 我刚做了,谢谢。
  • 为什么您的预期结果中的AssociatedType_ID for ClientCase_ID = '02' 设置为24?我们不希望它是04吗?
  • 您能详细解释一下您的逻辑吗?为什么要在AssociatedType 中获得MAX

标签: sql sql-server tsql join


【解决方案1】:

要在选择中获取 AssocId,您必须进行自加入。

左外连接 (您的子选择包含 max(AssociatedType))AS Astp

INNER JOIN T_AssociatedType AS Astp2 ON(无论该表上的主键是什么)

然后你可以将astp2.AssociationTypeId添加到原来的SELECT中。

【讨论】:

  • 感谢您的帮助。
【解决方案2】:

你可以试试这个查询。

CASE WHEN 中根据order 条件生成rn

您可以使用Rank窗口函数在子查询中制作排名号,然后获取rnk=1数据行。

;WITH CTE AS (
  SELECT ClientCase_ID,
          AssociatedPerson_ID,
          AssociatedPersonType,
          AssociatedType_ID,
          RANK() OVER(PARTITION BY ClientCase_ID ORDER BY rn desc,AssociatedPerson_ID) rnk
      FROM (
        SELECT t1.ClientCase_ID,
               t1.AssociatedPerson_ID,
               t1.AssociatedPersonType,
               t1.AssociatedType_ID,
                (CASE 
                 WHEN t1.AssociatedPersonType = 'ResPonsible Party'  then 16
                 WHEN t1.AssociatedPersonType = 'Primary Physician'  then 15
                 ELSE 14
                 END) rn
        FROM T t1 
        INNER JOIN T t2 ON t1.ClientCase_ID = t2.AssociatedPerson_ID 
        UNION ALL 
        SELECT t2.AssociatedPerson_ID,
               t1.AssociatedPerson_ID,
               t1.AssociatedPersonType,
               t2.AssociatedType_ID,
                (CASE 
                 WHEN t2.AssociatedPersonType = 'ResPonsible Party'  then 16
                 WHEN t2.AssociatedPersonType = 'Primary Physician'  then 15
                 ELSE 14
                 END) rn
        FROM T t1 
        INNER JOIN T t2 ON t1.ClientCase_ID = t2.AssociatedPerson_ID
    ) t1
)
select DISTINCT ClientCase_ID,AssociatedPerson_ID,AssociatedPersonType,AssociatedType_ID
FROM CTE 
WHERE rnk = 1

sqlfiddle


另外,您可以尝试使用带值的CROSS APPLY 而不是UNION ALL

;with CTE AS (
SELECT v.*, (CASE 
                 WHEN v.AssociatedPersonType = 'ResPonsible Party'  then 16
                 WHEN v.AssociatedPersonType = 'Primary Physician'  then 15
                 ELSE 14
             END) rn
FROM T t1 
INNER JOIN T t2 ON t1.ClientCase_ID = t2.AssociatedPerson_ID
CROSS APPLY (VALUES 
             (t1.ClientCase_ID,t1.AssociatedPerson_ID,t1.AssociatedPersonType,  t1.AssociatedType_ID),
             (t2.AssociatedPerson_ID,t1.AssociatedPerson_ID,t2.AssociatedPersonType, t2.AssociatedType_ID)
             )  v (ClientCase_ID,AssociatedPerson_ID,AssociatedPersonType,AssociatedType_ID)
)
SELECT distinct ClientCase_ID,AssociatedPerson_ID,AssociatedPersonType,AssociatedType_ID
FROM 
(
  SELECT *, 
         RANK() OVER(PARTITION BY ClientCase_ID ORDER BY rn desc,AssociatedPerson_ID) rnk
  FROM CTE
) t1
WHERE rnk = 1

sqlfiddle

注意

您可以在CASE WHEN添加您的客户订单号

[结果]

| ClientCase_ID | AssociatedPerson_ID | AssociatedPersonType | AssociatedType_ID |
|---------------|---------------------|----------------------|-------------------|
|            01 |                  01 |    ResPonsible Party |                16 |
|            02 |                  03 |  Physician Therapist |                24 |

【讨论】:

  • 感谢您的帮助。您的回答帮助我找到了自己的解决方案。
【解决方案3】:

我用下面的代码解决了这个问题:

 LEFT OUTER JOIN T_ClientAssociatedPerson Clas
    on Clas.ClientCase_ID = Ltst.ClientCase_ID
    and
        CASE
        WHEN Clas.AssociatedType_ID = 16 AND Clas.ClientCase_ID = Ltst.ClientCase_ID THEN 1
        WHEN Clas.AssociatedType_ID <> 16 AND Clas.AssociatedType_ID = (
            SELECT TOP 1 Clas.AssociatedType_ID
            FROM T_ClientAssociatedPerson Clas
            WHERE Clas.ClientCase_ID  = Ltst.ClientCase_ID
            ORDER BY AssociatedType_ID DESC
        ) THEN 1
        ELSE 0
        END = 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    相关资源
    最近更新 更多