2

我有一个查询显示一堆关于人员的信息,以及他们是否曾经存在过一组 dxcode。每一列都是对同一张表中另一组 dxcode 的不同检查:

示例输出:

pid . . . .HTN . . .DM  
123 . . . Y . . . . .N  
456 . . . N . . . . .N  

询问:

select  
    p.pid
    ,CASE WHEN HTN.pid is not null THEN 'Y' ELSE 'N' END AS HTN   
    ,... (other case statements)
from p

left outer join (  
    SELECT dx.pid, max(create_timestamp) as maxdate  
    FROM pdx  
    WHERE pdx.dxcode IN ('401','401.0','401.1','401.9')  
    group by dx.pid  
    ) as HTN on p.pid = HTN.pid

...其他连接同一个 pdx 表以查询其他 dx 代码是否存在

我的查询有效,但我认为它没有尽可能高效。我真的不需要 maxdate 来做任何事情,但它确实有效。在此之前,我使用的是 select distinct person,但意识到它必须做多少后处理,并且查询性能已经大大提高。对于最佳实践,我认为使用 max 仅返回一个结果的额外计算仍然是不必要的计算。

我尝试使用exists、left join、top 1 1 和case 语句的变体来做同样的事情,但我只是没有正确执行代码。

谢谢。我知道这必须是一个简单的答案。我一直在寻找的术语并没有得到我希望的答案。

4

2 回答 2

2

不确定这是否更有效,但看起来更简单。

SELECT
 p.pid,
 MAX(CASE WHEN pdx.dxcode IN ('401','401.0','401.1','401.9') THEN 'Y' ELSE 'N' END) AS HTN,
 MAX(CASE WHEN pdx.dxcode IN ('501','501.0','501.1','501.9') THEN 'Y' ELSE 'N' END) AS DM,
 MAX(CASE WHEN pdx.dxcode IN ('601') THEN 'Y' ELSE 'N' END) AS XN
FROM p
LEFT OUTER JOIN pdx ON p.pid = pdx.pid
GROUP BY
 p.pid

请参阅SQL 小提琴

更新:

如果您希望摆脱 MAX 以使其在第一个正匹配时停止,请尝试此操作。

SELECT
 DISTINCT
 p.pid,
 CASE WHEN EXISTS (SELECT 1 FROM pdx WHERE p.pid = pdx.pid AND pdx.dxcode IN ('401','401.0','401.1','401.9')) THEN 'Y' ELSE 'N' END AS HTN,
 CASE WHEN EXISTS (SELECT 1 FROM pdx WHERE p.pid = pdx.pid AND pdx.dxcode IN ('501','501.0','501.1','501.9')) THEN 'Y' ELSE 'N' END AS DM,
 CASE WHEN EXISTS (SELECT 1 FROM pdx WHERE p.pid = pdx.pid AND pdx.dxcode IN ('601')) THEN 'Y' ELSE 'N' END AS XN
FROM p
;

你可以试试这个,它会先得到不同的 pid,然后为每个找到第一个正匹配。

WITH pd AS (SELECT DISTINCT p.pid FROM p)
SELECT
 pd.pid,
 CASE WHEN EXISTS (SELECT 1 FROM pdx WHERE pd.pid = pdx.pid AND pdx.dxcode IN ('401','401.0','401.1','401.9')) THEN 'Y' ELSE 'N' END AS HTN,
 CASE WHEN EXISTS (SELECT 1 FROM pdx WHERE pd.pid = pdx.pid AND pdx.dxcode IN ('501','501.0','501.1','501.9')) THEN 'Y' ELSE 'N' END AS DM,
 CASE WHEN EXISTS (SELECT 1 FROM pdx WHERE pd.pid = pdx.pid AND pdx.dxcode IN ('601')) THEN 'Y' ELSE 'N' END AS XN
FROM pd 
GROUP BY
 pd.pid
;

那些 2 的 SQL Fiddle

于 2013-08-01T17:40:39.470 回答
1

也许将您的 CASE 语句更改为 WHEN HTN.pid IS NOT NULL THEN 1 ELSE 0 END 之类的东西,对每个案例求和,然后将最终的 SELECT 包裹在整个事情上?然后,例如,当 HTN > 0 THEN Y ELSE N?

select
    pid,
    case when HTN > 0 then 'Y' else 'N' end AS 'HTN',
    case when DM > 0 then 'Y' else 'N' end AS 'DM',
    case when CBG > 0 then 'Y' else 'N' end AS 'CBG',
    case when XYZ > 0 then 'Y' else 'N' end AS 'XYZ',
    case when DB > 0 then 'Y' else 'N' end AS 'DB'
from (  
        select
            p.pid,
            sum(case when pdx.dxcode in ('409', '409.1', '409.3') then 1 else 0 end) as 'HTN',
            sum(case when pdx.dxcode in ('899', '899.1', '892.2') then 1 else 0 end) as 'DM',
            sum(case when pdx.dxcode in ('410.0', '419.1', '419.3') then 1 else 0 end) as 'CBG',
            sum(case when pdx.dxcode in ('250', '250.1', '250.3') then 1 else 0 end) as 'XYZ',
            sum(case when pdx.dxcode in ('58.0', '58.1', '58.3') then 1 else 0 end) as 'DB'
        from
            person p left join
            pdx on
                p.pid = pdx.pid
        group by p.pid
    ) as dx
于 2013-08-01T17:04:37.293 回答