2012-11-21 75 views
0

我有一個相當大的查詢選擇某個日期範圍內的數據。有沒有比聯盟所有更簡單的方法?

我想根據年份對數據進行分組。

現在我有:

;with mappingTable as 
(
select b.CLIENT_ID,f.patient_id,f.received_date,f.SPECIMEN_ID 
from F_ACCESSION_DAILY f 
join 
(
select f.client_id,a.patient_id 
from 
(
SELECT 
     max(received_date) AS received_date 
    , patient_id   AS Patient_ID 
FROM F_ACCESSION_DAILY 
group by PATIENT_ID 
) a 
join F_ACCESSION_DAILY f 
on f.PATIENT_ID=a.Patient_ID 
and f.RECEIVED_DATE=a.received_date 
) b 
on b.Patient_ID=f.PATIENT_ID 
where f.RECEIVED_DATE between '20100101' and '20110101' - as you can see this data is only for 2010 
) ---there's much more to this query 

,你可以看到這個數據只適用於2010

,但我想對所有年做union all:2008年,2009年,2010年,2011年,2012 ...

我該如何做到這一點,而不用重寫查詢5次,並在它們之間做了union all

這裏的整個怪物查詢:

;with mappingTable as 
(
select b.CLIENT_ID,f.patient_id,f.received_date,f.SPECIMEN_ID 
from F_ACCESSION_DAILY f 
join 
(
select f.client_id,a.patient_id 
from 
(
SELECT 
     max(received_date) AS received_date 
    , patient_id   AS Patient_ID 
FROM F_ACCESSION_DAILY 
group by PATIENT_ID 
) a 
join F_ACCESSION_DAILY f 
on f.PATIENT_ID=a.Patient_ID 
and f.RECEIVED_DATE=a.received_date 
) b 
on b.Patient_ID=f.PATIENT_ID 
where f.RECEIVED_DATE between '20100101' and '20110101' 
) 
, 
    counted as(
SELECT 
PATIENT_ID, 
    client_id, 
    --case when COUNT(*)>=12 then 12 else COUNT(*) end TimesTested, 
    COUNT(*) as timestested, 
    case when count(*)>1 then 
    (datediff(day,MIN(received_date),max(received_date))) 
    /(COUNT(*)-1) 
else 
0 
end as testfreq 
    FROM mappingTable 
    GROUP BY 
    client_id, 
    patient_id  

),counted2 as (
    SELECT 
    client_id, 
    TimesTested, 
    CAST(COUNT(*) AS varchar(30)) AS count, 
    CAST(AVG(testfreq) as varchar(30)) as TestFreq, 
    CAST(STDEV(TestFreq) as varchar(30)) Stdv 
    FROM counted 
    GROUP BY 
    client_id, 
    TimesTested 
    ), 







    counted3 as 
    (
    SELECT 
    patient_id, 
    client_id, 
    TimesTested, 
    CAST(COUNT(*) AS varchar(30)) AS count, 
    AVG(testfreq) as TestFreq 
    FROM counted 
    GROUP BY 
    client_id, 
    TimesTested, 
    PATIENT_ID 
    ) 
    , 
    CountOver12 as 
    ( select client_id,count(*) count 
    from counted 
    where timestested>12 
    group by CLIENT_ID) 
    , 
    TotalAvgTestFreq as (

    select client_id, SUM(testfreq)/count(testfreq) TotalAvgTestFreq 
    from counted3 
    group by client_id 
    ) 



    , 
unpivoted AS (
    SELECT 
    client_id, 
    ColumnName + CAST(TimesTested AS varchar(10)) AS ColumnName, 
    ColumnValue 
    FROM counted2 
    UNPIVOT (
    ColumnValue FOR ColumnName IN (count, TestFreq,stdv) 
) u 
), 
pivoted AS (
    SELECT 
    client_id clientid, 
    count1, TestFreq1,stdv1, 
    count2, TestFreq2,stdv2, 
    count3, TestFreq3,stdv3, 
    count4, TestFreq4,stdv4, 
    count5, TestFreq5,stdv5, 
    count6, TestFreq6,stdv6, 
    count7, TestFreq7,stdv7, 
    count8, TestFreq8,stdv8, 
    count9, TestFreq9,stdv9, 
    count10, TestFreq10,stdv10, 
    count11, TestFreq11,stdv11, 
    count12, TestFreq12,stdv12 
    FROM unpivoted 
    PIVOT (
    MAX(ColumnValue) FOR ColumnName IN (
     count1,TestFreq1,stdv1, 
     count2,TestFreq2,stdv2, 
     count3,TestFreq3,stdv3, 
     count4,TestFreq4,stdv4, 
     count5,TestFreq5,stdv5, 
     count6,TestFreq6,stdv6, 
     count7,TestFreq7,stdv7, 
    count8, TestFreq8, stdv8, 
    count9, TestFreq9, stdv9, 
    count10, TestFreq10,stdv10, 
    count11, TestFreq11,stdv11, 
    count12, TestFreq12,stdv12 
    ) 
) p 
) 
, 
PatientStats as 
(
select 
distinct 
f.client_id 
,datediff(MM,c.mlis_date_established,GETDATE()) MonthsCustomer 
,count(distinct patient_id) TotalPatients 
,count(distinct specimen_id) TotalSpecimens 
from mappingTable f 
left join D_CLIENT c 
on f.CLIENT_ID=c.CLIENT_ID 
group by f.client_id,c.mlis_date_established 
) 
, 
Over12 
as 
(
select client_id,SUM(c) sumcount from 
(
select CLIENT_ID,COUNT(*) c 
from mappingTable 
group by CLIENT_ID,PATIENT_ID 
having count(*)>12 
) a 
group by client_id 
), 
GetMedian as(

    select client_id, avg(timestested) median_testfreq 
from 
(
    select client_id, 
      timestested, 
      rn=row_number() over (partition by CLIENT_ID 
           order by timestested), 
      c=count(timestested) over (partition by CLIENT_ID) 
    from counted3 
    where timestested>1 
) g 
where rn in (round(c/2,0),c/2+1) 
group by client_id 
    ) 
, final as (
SELECT p.*,pivoted.*,c12.count [Count13+],Over12.sumcount SumofGreaterThan12,t.TotalAvgTestFreq,median.median_testfreq 
FROM pivoted 
left join PatientStats p 
on p.CLIENT_ID=pivoted.CLIENTID 
left join Over12 
on over12.CLIENT_ID=p.CLIENT_ID 
left join TotalAvgTestFreq t 
on t.CLIENT_ID=p.CLIENT_ID 
left join CountOver12 C12 
on c12.CLIENT_ID=p.CLIENT_ID 
left join GetMedian median 
on median.CLIENT_ID=p.CLIENT_ID 
where p.CLIENT_ID not in (select CLIENTid from SalesDWH..TestPractices) 
) 
/* Get the data into a temp table */ 
SELECT * INTO #TempTable 
FROM final 
/* Drop the cloumns that are not needed */ 
ALTER TABLE #TempTable 
DROP COLUMN clientid 
/* Get results and drop temp table */ 
SELECT * FROM #TempTable 
DROP TABLE #TempTable 
+0

沒有看到任何數據等我只能問你爲什麼將記錄限制在一個小的數據集?如果你只是說你想要所有具有'f.RECEIVED_DATE> ='20080101''的數據,那麼你將得到一切,你不必'全部'。 – Taryn

+0

@bluefeet我想按年分組數據。請讓我知道如果有什麼不清楚! –

+0

@aptem然後用最後的結果使用'GROUP BY DatePart(year,RECEIVED_DATE)' – Taryn

回答

1

創建一個表函數:

CREATE FUNCTION fn_get_data_by_date_range 
(
    @start AS VARCHAR(8), 
    @end AS VARCHAR(8) 
) 
RETURNS TABLE 
AS 
RETURN 
(
    ...your query... 
    WHERE f.RECEIVED_DATE BETWEEN @start AND @end 
) 

那麼你可以UNION不同的是函數的調用:

SELECT * FROM fn_get_data_by_date_range('20100101','20110101') 
UNION ALL 
SELECT * FROM fn_get_data_by_date_range('20090101','20100101') 
UNION ALL 
.... 
UNION ALL 
SELECT * FROM fn_get_data_by_date_range('20070101','20080101') 
+0

嚇壞了真棒的想法!!!!!!! –

+0

thansk這麼多,這是一個輝煌的答案! –

相關問題