1

私は会社の連絡先のデータベースを持っています。異なる部門の会社ごとに複数の連絡先。各企業には、売上高と業界データが添付されています。

最近追加された上位 10 件の連絡先 (unix タイムスタンプ) を表示するクエリを作成する必要がありますが、すべてのマーケティング連絡先にはなりたくありません (上位 10 件であっても)。代わりに上位 100 件を確認したいと考えています。さまざまな部門からの 10 人の連絡先を取得します。したがって、トップ 10 がすべてマーケティングである代わりに、マーケティングが 2 つ、IT が 2 つ、HR が 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 タイプは 1 つだけです。また、返される行は 10 行だけですが、明らかに、行ごとに連絡先コードごとに 1 行を取得するには、クエリで 10 行以上を調べる必要があります。

これはクエリだけで可能ですか?または、クエリの結果を絞り込むために必要なロジックを適用するために、プログラムで何かを行う必要があります。

4

1 に答える 1

3

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;

一時テーブルには、カウンターを持つすべての連絡先が保持されます。カウンターは、同じ contact_code の連絡先ごとに増加します。そのため、特定の連絡先コードを持つ最新の連絡先はカウンター = 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:=@i+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;

これは基本的に一時テーブルのオプションと同じですが、前の列のデータをグローバル変数に格納することにより、その場でカウンターを作成します。面倒ですが、単一のクエリ内で使用できます。

于 2013-04-16T11:49:16.407 に答える