2016-01-13 76 views
1

我使用的是SAS大學版爲下表分析(實際上有它2.5M行)如何索引自連接

p_id c_id startyear endyear 
0001 3201  2008 2013 
0001 2131  2013 2015 
0013 3201  2006 2010 

其中的p_id是爲person_id和C_ID是companyid。

我想獲得同事的數量在一定的一年,所以我創建了一個表的不同p_ids並做以下查詢(即重疊的跨度期間,在同一公司工作的人數):

PROC SQL; 

UPDATE no_colleagues AS t1 
SET c2007 = (
    SELECT COUNT(DISTINCT t2.p_id) - 1 
    FROM table AS t2 
    INNER JOIN table AS t3 
    ON t3.p_id = t1.p_id 
    AND t3.c_id = t2.c_id 
    AND t3.startyear <= t2.endyear % checks overlapping criteria 
    AND t3.endyear >= t2.startyear % checks overlapping criteria 
    AND t3.startyear <= 2007   % limits number of returns 
    AND t2.startyear <= 2007   % limits number of returns 
); 

索引查詢(p_id,c_id,startyear,endyear)的單個查找需要0.04秒。上面的查詢對於單個更新大約需要1.8秒,並且不使用任何索引。

所以我的問題是:

如何提高查詢,和/或如何使用索引,以確保自連接可以使用索引?

在此先感謝。

+0

請武官'EXPLAIN'計劃。 –

回答

0

一種更有效的方法,包括:

1)的結果,而不是寬格式創建一個長格式表。這將更容易填充,並且稍後更容易工作。

create table colleagues_by_year (
    p_id int, 
    year int, 
    colleagues int 
); 

現在可以使用單個insert聲明來填充該聲明。唯一的竅門是在決賽桌上獲得你想要的年份的完整列表。有幾個選項,但是因爲我對SAS SQL不太熟悉,所以我將使用一個非常簡單的選項:一個可以加入的年份查找表。

create table years (
    year int 
); 

insert into years 
    values (2007),(2008),... 

(更復雜的方法是發現輸入數據中所有年份的範圍的遞歸查詢)。

現在最終插入:

insert into colleagues_by_year 
    select p_id, 
      year, 
      count(*) 
     from colleagues 
     join years on 
      years.year between colleagues.startyear and colleagues.endyear 
     group by p_id,year 

這不會有同事之間的全年數量將是0。如果你想,你可以做幾年是左連接,並只算任何行years.year不爲空的行。

1

根據你的數據,我會這樣做,但也許你需要調整代碼以適應你的需求。

首先,用p_id,c_id,year創建一個表格。 因此,您在3201公司工作的第一個人將在此表中有6個觀察值,每個工作年度有一個觀察值。

data have_count; 
    set have; 

do i=startyear to endyear; 
    worked_in = i; 
    output; 
end; 

drop i startyear endyear; 
run; 

現在你只算和agreggate:

proc sql; 
select 
    worked_in as year 
    ,c_id 
    ,count(distinct p_id) as no_colleagues 
from have_count 
group by 1,2; 
quit; 

結果:

year c_id no_colleagues 
2006 3201 1 
2007 3201 1 
2008 3201 2 
2009 3201 2 
2010 3201 2 
2011 3201 1 
2012 3201 1 
2013 2131 1 
2013 3201 1 
2014 2131 1 
2015 2131 1 
相關問題