2016-05-06 2 views
2

У меня есть assigns таблицу со следующими столбцами:Count первое вхождение со значением столбца по заказу другой колонке

id - int 
id_lead - int 
id_source - int 
date_assigned - int (this represents a unix timestamp) 

Теперь, позволяет сказать, что у меня есть следующие данные в этой таблице:

id id_lead id_source date_assigned 
1 20  5   1462544612 
2 20  6   1462544624 
3 22  6   1462544615 
4 22  5   1462544626 
5 22  7   1462544632 
6 25  6   1462544614 
7 25  8   1462544621 

Теперь давайте скажем, что я хочу получить количество строк, чей id_source равен 6, и является первой записью для каждого руководства (отсортировано по дате_знакомой по возрастанию).

Таким образом, в этом случае счетчик будет = 2, потому что есть 2 провода (id_lead 22 и 25), чья первая id_source является 6.

Как бы написать этот запрос так, чтобы он быстро и будет работать как выбрать подзапрос? Я думал, что-то вроде этого не работает:

select count(*) from `assigns` where `id_source`=6 order by `date_assigned` asc limit 1 

Я понятия не имею, как написать этот запрос оптимальным способом. Любая помощь будет оценена по достоинству.

+0

Проверьте мое обновление, я думаю, что простого запроса достаточно для вас – Sachin

ответ

0

псевдокод:

select rows 
with a.id_source = 6 
but only if 
    there do not exist any row 
     with same id_lead 
     and smaller date_assigned 

Перевести его в SQL

select *          -- select rows 
from assigns a 
where a.id_source = 6      -- with a.id_source = 6 
    and not exists (       -- but only if there do not exist any row 
    select 1 
    from assigns a1 
    where a1.id_lead = a.id_lead    -- with same id_lead 
     and a1.date_assigned < a.date_assigned -- and smaller date_assigned 
) 

Теперь замените select * на select count(*), и вы получите свой результат.

http://sqlfiddle.com/#!9/3dc0f5/7

Update:

Запрос NOT-EXIST можно переписать исключая LEFT JOIN запрос:

select count(*) 
from assigns a 
left join assigns a1 
    on a1.id_lead = a.id_lead 
    and a1.date_assigned < a.date_assigned 
where a.id_source = 6 
    and a1.id_lead is null 

Если вы хотите, чтобы получить количество для всех значений id_source, следующий запрос может быть самым быстрым:

select a.id_source, count(1) 
from (
    select a1.id_lead, min(a1.date_assigned) date_assigned 
    from assigns a1 
    group by a1.id_lead 
) a1 
join assigns a 
    on a.id_lead = a1.id_lead 
    and a.date_assigned = a1.date_assigned 
group by a.id_source 

Вы по-прежнему можете заменить group by a.id_source на where a.id_source = 6.

Запросы нуждаются в индексах на assigns(id_source) и assigns(id_lead, date_assigned).

+0

Я написал аналогичный запрос, но проблема в том, что я хочу, чтобы это было в подзапросе. подзапрос в подзапросе невозможно с оптимизационной точки зрения. спасибо за вашу помощь. – kjdion84

+0

@ kjdion84, если вы написали аналогичный запрос, вы должны были упомянуть об этом в своем вопросе и объяснить, почему это не решение. Однако (производный) подзапрос, возвращающий постоянное значение (в данном случае «2»), не должен быть проблемой. Если ваш подзапрос будет скоррелирован (somthing like: 'where a.id_source = outer.id_source'), тогда было бы лучше использовать мой последний запрос в JOIN вместо подзапроса. –