2013-04-16 26 views
1

我有公司的聯繫人數據庫。不同部門的每個公司有多個聯繫人。每家公司都附有營業額和行業數據。SQL查詢顯示具有均勻分佈值的頂級x記錄

我需要寫一個查詢,顯示前10名最近添加的聯繫人(unix時間戳),但我不希望它是所有的市場營銷聯繫人(即使前10名),我想看看排在前100位,並從不同部門獲得10位聯繫人。因此,而不是所有的營銷前10名,可能有2個營銷,2英尺,2個人力資源,2個人事。

所以我的查詢基本上是這樣的:

SELECT DISTINCT `surname`, `job_title`, `company_name` 
FROM (`company_database`) 
WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13') 
AND `turnover_code` IN ('5', '6', '7', '8') 
AND `contact_code` IN ('16', '17', '26', '27', '9', '10', '30', '31', '23', '24', '12', '13')  AND `industry_code` NOT IN ('22', '17', '35', '36') LIMIT 10 

但是,這只是返回一個唯一的行。我需要的是每個公司一個聯繫人,不超過1個contact_code類型。我也只想要返回10行,但顯然要獲得每行1個聯繫碼,查詢將需要超過10個。

這可能只是一個查詢嗎?或者,我應該通過編程來應用所需的邏輯來減少查詢結果。

+0

請張貼架構,一些樣本數據和所需的輸出 –

+0

哪一個更重要? contact_code或公司? 「每個公司一個聯繫人並且不超過1個contact_code類型」並不總是可能的。 –

回答

2

你可以使用myisam引擎和一個技巧來使用臨時表。

如果創建以下臨時表:

create table tmp_company_sequence 
( surname varchar(255) 
    ,job_title varchar(255) 
    ,company_name varchar(255) 
    ,date_added date 
    ,contact_code int 
    ,counter int auto_increment 
    ,primary key (contact_code,counter) 
); 

現在

insert into `tmp_company_sequence`(`surname`, `job_title`, `company_name`,`contact_code`,`date_added`) 
SELECT DISTINCT `surname`, `job_title`, `company_name`,`contact_code`,`date_added` 
FROM (`company_database`) 
WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13') 
AND `turnover_code` IN ('5', '6', '7', '8') 
AND `contact_code` IN ('16', '17', '26', '27', '9', '10', '30', '31', '23', '24', '12', '13')  AND `industry_code` NOT IN ('22', '17', '35', '36') 
order by contact_code, added_date desc; 

你的臨時表,現在將保留所有與抗衡的聯繫人。對於同一聯繫人代碼的每個聯繫人,計數器都會增加。因此,與某個聯繫人代碼的最新聯繫人將具有計數器= 1,下一個最近將具有計數器= 2,依此類推。

你現在可以做一個

select * 
from tmp_company_sequence 
order by counter asc, date_added desc 
limit 10; 

這會給你增加對所有contact_codes最新的聯繫人列表。

編輯:

我才意識到這可能是與一個單一的查詢來完成,但它更是難看:

SELECT `surname` 
    , `job_title` 
    , `company_name` 
    , `contact_code` 
FROM(
    SELECT 
    `surname` 
    , `job_title` 
    , `company_name` 
    , `contact_code` 
    , `date_added` 
    , IF(contact_code = @prev_contact_code,@i:[email protected]+1,@i:=1) AS counter 
    , @prev_contact_code = contact_code 
    FROM 
    (`company_database`) 
    ,(SELECT @i := 1) 
    WHERE `employee_code` IN ('6', '7', '8', '9', '10', '11', '12', '13') 
    AND `turnover_code` IN ('5', '6', '7', '8') 
    AND `contact_code` IN (
     '16' 
     , '17' 
     , '26' 
     , '27' 
     , '9' 
     , '10' 
     , '30' 
     , '31' 
     , '23' 
     , '24' 
     , '12' 
     , '13' 
    ) 
    AND `industry_code` NOT IN ('22', '17', '35', '36') 
    ORDER BY contact_code 
    , added_date DESC) sub 
WHERE counter = 1 
ORDER BY added_date DESC 
LIMIT 10; 

這確實基本相同,與臨時表的選項,但它通過在全局變量中存儲來自前一列的數據來即時創建計數器。它很混亂,但可以在單個查詢中使用。

+0

我想我喜歡你的第一個解決方案!有一張臨時桌是沒有問題的,所以我認爲,爲了清晰起見,我會爲那一張去!謝謝!! – John

+0

嗯,你的表定義不起作用,mysql說:「不正確的表定義;只能有一個自動列,它必須定義爲一個鍵」 – John

+0

HI John,第一個建議只在MyISAM中有效。 SOrry應該將ENGONE = MYISAM添加到create table語句中。 –