2014-01-07 2 views
0

У меня есть данные, что выглядит следующим образом:Использование MAX() и ROW_NUMBER(), чтобы избавиться от дублирования данных в SQL Server 2008 R2

B_Pt_No | MRN | B_Adm_Date | B_Dsch_Date | B_Days_Stay | B_Days_To_Readmit  
123  | 1234 | 4/3/2013 | 4/10/2013 | 7   | 30  
123  | 1234 | 4/3/2013 | 4/10/2013 | 7   | 30 
125  | 1229 | 4/9/2013 | 4/22/2013 | 13   | 23  

Я получаю данные, используя следующий запрос:

-- VARIABLE INITIALIZATION AND DECLARATION 
DECLARE @SD AS DATE; 
DECLARE @ED AS DATE; 
SET @SD = '2011-01-01'; 
SET @ED = '2013-12-31'; 

-- COLUMN SELECTION 
SELECT DISTINCT B_Pt_No AS [READMIT ENCOUNTER] 
, B_Med_Rec_No AS [MRN] 
, B_Adm_Src_Desc AS [READMIT SOURCE] 
, CAST(B_Adm_Date AS DATE) AS [READMIT DATE] 
, CAST(B_Dsch_Date AS DATE) AS [READMIT DISC DATE] 
, DATEPART(MONTH, B_Dsch_Date) AS [READMIT MONTH] 
, DATEPART(YEAR, B_Dsch_Date) AS [READMIT YEAR] 
, B_Days_Stay AS [LOS] 
, MAX(B_Days_To_Readmit) OVER (PARTITION BY B_PT_NO) AS [INTERIM] <-- trouble 
, CASE 
    WHEN B_Pyr1_Co_Plan_Cd = '*' 
    THEN 'SELF PAY' 
    ELSE B_Pyr1_Co_Plan_Cd 
    END AS [READMIT INSURANCE] 
, B_Mdc_Name AS [READMIT MDC] 
, B_Drg_No AS [READMIT DRG] 
, B_Clasf_Desc AS [READMIT DX CLASF] 
, B_Readm_Adm_Dr_Name AS [READMIT ADMITTING DR] 
, B_Readm_Atn_Dr_Name AS [READMIT ATTENDING DR] 
, B_Hosp_Svc AS [READMIT HOSP SVC] 

-- DB USED 
FROM smsdss.c_readmissions_v 

-- FILTER(S) USED 
/* 
THE FIRST FILTER IS STATING THAT WE ONLY WANT MRN'S THAT HAVE HAD A 
DRG FROM A CERTAIN GROUP. 
*/ 
WHERE B_Med_Rec_No IN (
    SELECT DISTINCT MED_REC_NO 

    FROM smsdss.BMH_PLM_PtAcct_V 

    WHERE Plm_Pt_Acct_Type = 'I' 
    AND PtNo_Num < '20000000' 
    AND Dsch_Date BETWEEN @SD AND @ED 
    AND drg_no IN (  -- DRG'S OF INTEREST 
     '190','191','192' -- COPD 
     ,'291','292','293' -- CHF 
     ,'193','194','195' -- PN 
    ) 
) 
AND B_Dsch_Date BETWEEN @SD AND @ED 
AND B_Adm_Src_Desc != 'Scheduled Admission' 
AND B_Pt_No < '20000000' 

До сих пор запрос работал очень хорошо, и есть только два дубликата, подобных тому, который указан в данных примера. Я использую DISTINCT для VISIT_ID и используя MAX(B_DAYS_TO_READMIT) OVER (PARTITION BY B_PT_NO), чтобы получить максимальные дни между посещениями. Проблема, с которой я столкнулся, заключается в том, что столбец INTERIM имеет то же значение в двух строках. Можно ли использовать какую-то комбинацию MAX() и ROW_NUMBER(), чтобы получить только один из них?

Спасибо,

+3

Вы просто пытаетесь устранить дубликат, и взять последнюю реадмиссии DATE для каждого VISIT_ID? Можете ли вы добавить некоторую консистенцию здесь? Образцы данных показывают VISIT_ID и READMIT DATE, но ссылки на запросы B_PT_NO и B_Days_To_Readmit. Не могли бы вы также нанести вред человеку, который называет эти столбцы? И, наконец, пожалуйста, не используйте «одиночные кавычки» для разграничения псевдонимов - этот синтаксис устарел в некоторых формах, а также делает ваши псевдонимы похожими на строковые значения. При необходимости используйте '[квадратные скобки]' (или просто не используйте псевдонимы, требующие экранирования). –

+0

Да, я пытаюсь устранить дубликат и принять последнюю дату READMIT DATE для каждого VISIT_ID, я исправлю проблему согласованности. Не думал, что «одинарные кавычки» были устаревшими, я буду придерживаться «[скобок]». –

+2

@AaronBertrand +1 для похлопывания указанных лиц. –

ответ

4
;WITH cte AS 
(
    SELECT B_Pt_No AS [READMIT ENCOUNTER] 
    , B_Med_Rec_No AS MRN 
    , B_Adm_Src_Desc AS [READMIT SOURCE] 
    , CAST(B_Adm_Date AS DATE) AS [READMIT DATE] 
    , CAST(B_Dsch_Date AS DATE) AS [READMIT DISC DATE] 
    , DATEPART(MONTH, B_Dsch_Date) AS [READMIT MONTH] 
    , DATEPART(YEAR, B_Dsch_Date) AS [READMIT YEAR] 
    , B_Days_Stay AS LOS 
    , B_Days_To_Readmit AS INTERIM 
    , CASE WHEN B_Pyr1_Co_Plan_Cd = '*' THEN 'SELF PAY' 
      ELSE B_Pyr1_Co_Plan_Cd END AS [READMIT INSURANCE] 
    , B_Mdc_Name AS [READMIT MDC] 
    , B_Drg_No AS [READMIT DRG] 
    , B_Clasf_Desc AS [READMIT DX CLASF] 
    , B_Readm_Adm_Dr_Name AS [READMIT ADMITTING DR] 
    , B_Readm_Atn_Dr_Name AS [READMIT ATTENDING DR] 
    , B_Hosp_Svc AS [READMIT HOSP SVC] 
    , rn = ROW_NUMBER() OVER (PARTITION BY B_Pt_No ORDER BY B_Adm_Date DESC) 
    FROM smsdss.c_readmissions_v AS r 
    WHERE EXISTS 
    (
    SELECT 1 FROM smsdss.BMH_PLM_PtAcct_V 
     WHERE Plm_Pt_Acct_Type = 'I' 
     AND PtNo_Num < '20000000' 
     AND Dsch_Date BETWEEN @SD AND @ED 
     AND drg_no IN ('190','191','192' -- COPD 
      ,'291','292','293' -- CHF 
      ,'193','194','195' -- PN 
    ) AND MED_REC_NO = r.B_Med_Rec_No 
) 
    AND B_Dsch_Date BETWEEN @SD AND @ED 
    AND B_Adm_Src_Desc != 'Scheduled Admission' 
    AND B_Pt_No < '20000000' 
) 
SELECT * FROM cte WHERE rn = 1; 
+0

Благодарим за помощь Аарона. –