3

我有一个查询,我想在发生某事的情况下返回某些结果,并拒绝发生某事的其他人,并进一步拒绝未发生某事的其他人。

这是当前的示例输出:

VISIT ID | MRN | ORD NUM | ORD STS | ORD DESC
123456   | 123 | 987654  | ACTIVE  | URINE TEST
123456   | 123 | 987654  | IN PROG | URINE TEST
123456   | 123 | 987654  | COMPLETE| URINE TEST
123456   | 123 | 987321  | ACTIVE  | INSERT FOLEY
123456   | 123 | 987321  | IN PROG | INSERT FOLEY
123456   | 123 | 987321  | COMPLETE| INSERT FOLEY
124578   | 321 | 654321  | ACTIVE  | URINE TEST
124578   | 321 | 654321  | IN PROG | URINE TEST
124578   | 321 | 654321  | COMPLETE| URINE TEST
END OF REPORT

我想要的输出如下:

VISIT ID | MRN | ORD NUM | ORD STS | ORD DESC
123456   | 123 | 987654  | ACTIVE  | URINE TEST
123456   | 123 | 987654  | IN PROG | URINE TEST
123456   | 123 | 987654  | COMPLETE| URINE TEST
123456   | 123 | 987321  | ACTIVE  | INSERT FOLEY
123456   | 123 | 987321  | IN PROG | INSERT FOLEY
123456   | 123 | 987321  | COMPLETE| INSERT FOLEY
END OF REPORT

INSERT FOLEY如果他们也有订单或/和订单,我只想查看有尿检的访问 ID REMOVE FOLEY。因此,如果我进来只是进行尿检,那么我不应该出现在报告上。

这是我的查询:

-- FOLEY CATHETER ORDERS

-- VARIABLE DECLARATION AND INITIALIZATION
DECLARE @SD DATETIME
DECLARE @ED DATETIME
SET @SD = '2013-06-01';
SET @ED = '2013-06-30';

-- COLUMN SELECTION
SELECT PV.PtNo_Num AS 'VISIT ID'
, PV.Med_Rec_No AS 'MRN'
, PV.vst_start_dtime AS 'ADMIT'
, PV.vst_end_dtime AS 'DISC'
, PV.Days_Stay AS 'LOS'
, PV.pt_type AS 'PT TYPE'
, PV.hosp_svc AS 'HOSP SVC'
, SO.ord_no AS 'ORDER NUMBER'
--, SO.ent_dtime AS 'ORDER ENTRY TIME'
--, DATEDIFF(HOUR,PV.vst_start_dtime,SO.ent_dtime) AS 'ADM TO ENTRY HOURS'
, CASE
    WHEN SO.svc_desc = 'INSERT FOLEY CATHETER' THEN 'INSERT FOLEY'
    WHEN SO.svc_desc = 'INSERT INDWELLING URINARY CATHETER TO GRAVITY DRAINAGE' THEN 'INSERT FOLEY'
    WHEN SO.svc_desc = 'REMOVE INDWELLING URINARY CATHETER' THEN 'REMOVE FOLEY'
    ELSE SO.svc_desc
  END AS 'ORD DESC'
, CASE
    WHEN OSM.ord_sts = 'ACTIVE' THEN '1 - ACTIVE'
    WHEN OSM.ord_sts = 'IN PROGRESS' THEN '2 - IN PROGRESS'
    WHEN OSM.ord_sts = 'COMPLETE' THEN '3 - COMPLETE'
    WHEN OSM.ord_sts = 'CANCEL' THEN '4 - CANCEL'
    WHEN OSM.ord_sts = 'DISCONTINUE' THEN '5 - DISCONTINUE'
    WHEN OSM.ord_sts = 'SUSPEND' THEN '6 - SUSPEND'
  END AS 'ORDER STATUS'
, SOS.prcs_dtime AS 'ORDER STATUS TIME'
, DATEDIFF(DAY,PV.vst_start_dtime,SOS.prcs_dtime) AS 'ADM TO ORD STS IN DAYS'

-- DB(S) USED
FROM smsdss.BMH_PLM_PtAcct_V PV
JOIN smsmir.sr_ord SO
ON PV.PtNo_Num = SO.episode_no
JOIN smsmir.sr_ord_sts_hist SOS
ON SO.ord_no = SOS.ord_no
JOIN smsmir.ord_sts_modf_mstr OSM
ON SOS.hist_sts = OSM.ord_sts_modf_cd

-- FILTER(S)
WHERE PV.Adm_Date BETWEEN @SD AND @ED
AND (SO.svc_desc LIKE 'INSERT FOLEY CATHETER'
    OR SO.svc_desc LIKE 'INSERT INDWELLING URINARY CATHETER TO GRAVITY DRAINAGE'
    OR SO.svc_desc LIKE 'REMOVE INDWELLING URINARY CATHETER'
    OR SO.svc_desc LIKE 'URIN%'
    )
-- TRYING TO KICK OUT PATIENTS WHO DID NOT GET A FOLEY CATHETER ORDER
-- OF ANY TYPE
--AND PV.PtNo_Num NOT IN (
--    SELECT SO.ord_no

--   FROM smsdss.BMH_PLM_PtAcct_V PV
--  JOIN smsmir.sr_ord SO
--  ON PV.PtNo_Num = SO.episode_no
--  JOIN smsmir.sr_ord_sts_hist SOS
--  ON SO.ord_no = SOS.ord_no
--  JOIN smsmir.ord_sts_modf_mstr OSM
--  ON SOS.hist_sts = OSM.ord_sts_modf_cd

--  WHERE (SO.svc_desc != 'INSERT FOELY CATHETER'
--        OR SO.svc_desc != 'INSERT INDWELLING URINARY CATHETER TO GRAVITY DRAINAGE'
--        OR SO.svc_desc != 'REMOVE INDWELLING URINARY CATHETER'
--        )
--)
-- KICKS OUT DISCONTINUED ORDERS
AND SO.ord_no NOT IN (
    SELECT SO.ord_no

    FROM smsdss.BMH_PLM_PtAcct_V PV
    JOIN smsmir.sr_ord SO
    ON PV.PtNo_Num = SO.episode_no
    JOIN smsmir.sr_ord_sts_hist SOS
    ON SO.ord_no = SOS.ord_no
    JOIN smsmir.ord_sts_modf_mstr OSM
    ON SOS.hist_sts = OSM.ord_sts_modf_cd

    WHERE OSM.ord_sts = 'DISCONTINUE'
    AND (SO.svc_desc LIKE 'INSERT FOLEY CATHETER'
    OR SO.svc_desc LIKE 'INSERT INDWELLING URINARY CATHETER TO GRAVITY DRAINAGE'
    OR SO.svc_desc LIKE 'REMOVE INDWELLING URINARY CATHETER'
    OR SO.svc_desc LIKE 'URINE%'
    )
)

我试图与其余部分一起工作的代码是完全被注释掉的部分。查询中的注释部分需要相当长的时间来运行含义t>5 minutes而没有返回结果。如果没有该部分,查询将返回所有结果t<2 minutes

提前致谢,

4

2 回答 2

2

一种方法是使用窗口聚合函数(例如MAX() OVER ...)来确定VISIT ID行组是否具有具有特定ORD DESC值的行。

基本上,模式将是这样的:

SELECT
  ...
  MAX(CASE WHEN [ORD DESC] = 'URINE TEST' THEN 1 ELSE 0 END)
    OVER (PARTITION BY [VISIT ID]) AS HasUrineTest,
  MAX(CASE WHEN [ORD DESC] IN ('INSERT FOLEY', 'REMOVE FOLEY') THEN 1 ELSE 0 END)
    OVER (PARTITION BY [VISIT ID]) AS HasInsertRemoveFoley
FROM ...

这将为您在每一行中标记列,每次访问具有相同的值。然后,您将使用这些标志来过滤行。但是,您需要将整个选择放入子查询中,并将其用作派生表,以便能够过滤标志列:

WITH flagged AS (
  SELECT
    ...
    MAX(CASE WHEN [ORD DESC] = 'URINE TEST' THEN 1 ELSE 0 END)
      OVER (PARTITION BY [VISIT ID]) AS HasUrineTest,
    MAX(CASE WHEN [ORD DESC] IN ('INSERT FOLEY', 'REMOVE FOLEY') THEN 1 ELSE 0 END)
      OVER (PARTITION BY [VISIT ID]) AS HasInsertRemoveFoley
  FROM  ...  -- all your joins
  WHERE ...  -- and filters
)
SELECT ...  -- repeat all the columns except the Has* flags
FROM flagged
WHERE HasUrineTest = 1
  AND HasInsertRemoveFoley = 1
;

您可能已经注意到我在窗口函数中使用了输出别名而不是底层名称或表达式。在实际实现中,[VISIT ID]可能需要替换为PV.PtNo_Num. 至于[ORD DESC],您可以在(子)查询中引入一个CROSS APPLY子句并将计算移到[ORD DESC]那里而不是现在计算的位置,如下所示:

WITH flagged AS (
  SELECT
     ...
     x.[ORD DESC],  -- instead of the CASE; the CASE is now in CROSS APPLY
     ...
  FROM ...  -- all your joins
  CROSS APPLY (
    SELECT
      CASE
        WHEN SO.svc_desc = 'INSERT FOLEY CATHETER' THEN 'INSERT FOLEY'
        WHEN SO.svc_desc = 'INSERT INDWELLING URINARY CATHETER TO GRAVITY DRAINAGE' THEN 'INSERT FOLEY'
        WHEN SO.svc_desc = 'REMOVE INDWELLING URINARY CATHETER' THEN 'REMOVE FOLEY'
        ELSE SO.svc_desc
      END AS [ORD DESC]
   ) x
)
SELECT ...
;
于 2013-07-18T19:57:24.953 回答
1

这是从我称为数据的输入表开始的。希望它仍然有一些帮助。

    ;With Data AS (

    SELECT 123456 [Visit ID], 123 MRN, 987654 [ORD NUM], 'ACTIVE' [ORD STS], 'URINE TEST' [ORD DESC]
    UNION ALL
    SELECT 123456 [Visit ID], 123 MRN, 987654 [ORD NUM], 'IN PROG' [ORD STS], 'URINE TEST' [ORD DESC]
    UNION ALL
    SELECT 123456 [Visit ID], 123 MRN, 987654 [ORD NUM], 'COMPOLETE' [ORD STS], 'URINE TEST' [ORD DESC]
    UNION ALL
    SELECT 123456 [Visit ID], 123 MRN, 987654 [ORD NUM], 'ACTIVE' [ORD STS], 'INSERT FOLEY' [ORD DESC]
    UNION ALL
    SELECT 123456 [Visit ID], 123 MRN, 987654 [ORD NUM], 'IN PROG' [ORD STS], 'INSERT FOLEY' [ORD DESC]
    UNION ALL
    SELECT 123456 [Visit ID], 123 MRN, 987654 [ORD NUM], 'COMPOLETE' [ORD STS], 'INSERT FOLEY' [ORD DESC]
    UNION ALL
    SELECT 124578 [Visit ID], 321 MRN, 654321 [ORD NUM], 'ACTIVE' [ORD STS], 'URINE TEST' [ORD DESC]
    UNION ALL
    SELECT 124578 [Visit ID], 321 MRN, 654321 [ORD NUM], 'IN PROG' [ORD STS], 'URINE TEST' [ORD DESC]
    UNION ALL
    SELECT 124578 [Visit ID], 321 MRN, 654321 [ORD NUM], 'COMPOLETE' [ORD STS], 'URINE TEST' [ORD DESC]

), VisitIDs AS (
    SELECT DISTINCT [Visit ID] FROM Data AS DataSource
    WHERE EXISTS (SELECT 1 FROM Data WHERE Data.[Visit ID] = DataSource.[Visit ID] AND [ORD DESC] = 'URINE TEST') 
        AND EXISTS(SELECT 1 FROM Data WHERE Data.[Visit ID] = DataSource.[Visit ID] AND [ORD DESC] = 'INSERT FOLEY' )
)
SELECT * FROM Data INNER JOIN VisitIDs ON Data.[Visit ID] = VisitIDs.[Visit ID]
于 2013-07-18T19:35:39.113 回答