2014-09-26 3 views
1

Я борюсь с призывом Mysql и надеялся одолжить ваш опыт.Mysql Уникальные записи, где есть несколько записей

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

У меня есть таблица, например, так:

+------------------+----------------------+-------------------------------+ 
|  username |  acctstarttime |  acctstoptime   | 
+------------------+----------------------+-------------------------------+ 
|  bill  | 22.04.2014   |   23.04.2014   | 
+------------------+----------------------+-------------------------------+ 
|  steve  | 16.09.2014   |        | 
+------------------+----------------------+-------------------------------+ 
|  fred  | 12.08.2014   |        | 
+------------------+----------------------+-------------------------------+ 
|  bill  | 24.04.2014   |        | 
+------------------+----------------------+-------------------------------+ 

Я хочу, чтобы выбрать только уникальные записи из столбца, т.е. имя пользователя, я только хочу одну запись для счета и мне нужна одна с самых последних датой_начала условии, что они были не были за последние три месяца (end_date для меня не важен), иначе я не хочу никаких данных. В итоге мне просто нужен кто-нибудь, где самая последняя дата начала - более 3 месяцев.

Команда Я использую в настоящее время является:

SELECT DISTINCT(username), ra.acctstarttime AS 'Last IP', ra.acctstoptime 
FROM radacct AS ra 
WHERE ra.acctstarttime < DATE_SUB(now(), interval 3 month) 
GROUP BY ra.username 
ORDER BY ra.acctstarttime DESC 

Однако, это просто дает мне подробности о date_start для этого конкретного клиента, где они имели дату начала более 3 месяцев назад. Я устал от нескольких других комбинаций этого и попробовал команду с двойным выбором, но сейчас я нажимаю кирпичные стены. Любая помощь или толчок в правильном направлении были бы высоко оценены.

Update

Я создал следующее: http://sqlfiddle.com/#!2/f47b2/1

Эффективно я должен видеть только 1 строку, если запрос, как это должно быть. Это будет строка для счета. Поскольку он единственный, у которого нет даты начала в течение последних трех месяцев. В результате я бы ожидал увидеть, заключается в следующем:

24 bill April, 11 2014 12:11:40+0000 (null) 

Поскольку это последняя дата начала счета, но эта дата начала не в течение последних трех месяцев. Надеюсь, это поможет прояснить ситуацию. Большое спасибо за вашу помощь.

http://sqlfiddle.com/#!2/f47b2/14

Это еще один пример. Если acctstartdate для счета будет отображаться как апрельская запись, тогда я мог бы добавить свое предложение where за последние три месяца, и это даст мне мой желаемый результат.

+0

Вы должны изменить свое сравнение ie'WHERE ra.acctstarttime> DATE_SUB (сейчас(), интервал 3 месяца) ' – sqlab

+0

@sqlab См. обновление в вопросе. Большое спасибо –

ответ

1

SQLFiddle http://sqlfiddle.com/#!2/444432/9 (MySQL 5.5)

Я смотрю на вопрос в 2 способами на основе текущего текста:

I only want one record for bill and I need the one with most recent start_date, providing they were in the last three months (end_date is not important to me here) else I do not want any data

Структура

create table test 
(
    username varchar(20), 
    date_start date 
); 

данных

Username date_start 
--------- ----------- 
bill  2014-09-25 
bill  2014-09-22 
bill  2014-05-26 
andy  2014-05-26 
tim   2014-09-25 
tim   2014-05-26 

Что мы хотим

Username date_start 
--------- ----------- 
bill  2014-09-25 
tim   2014-09-25 

Запрос

select * 
from test a 
inner join 
(
    select username, max(date_start) as max_date_start 
    from test 
    where date_start > date_sub(now(), interval 3 month) 
    group by username 
) b 
on 
    a.username = b.username 
    and a.date_start = b.max_date_start 
where 
    date_start > date_sub(now(), interval 3 month) 

Объяснение

Для самых последних последних 3-х месяцев, давайте получить максимальную начальную дату для каждого пользователя. Чтобы ограничить записи до последних 3 месяцев, мы используем where date_start > date_sub(now(), interval 3 month) и для того, чтобы найти максимальную дату начала для каждого пользователя, мы используем group by username.

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

Другой угол

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

Что мы хотим

Username date_start 
--------- ----------- 
bill  2014-05-26 
tim   2014-05-26 
andy  2014-05-26 

Запрос

select * 
from test a 
inner join 
(
    select username, max(date_start) as max_date_start 
    from test 
    where date_start < date_sub(now(), interval 3 month) 
    group by username 
) b 
on 
    a.username = b.username 
    and a.date_start = b.max_date_start 
where 
    date_start < date_sub(now(), interval 3 month) 

Надеемся, вы сможете изменить эти запросы по своему вкусу.

EDIT

на основе вашего хорошего объяснения, вот запрос SQLFiddle: http://sqlfiddle.com/#!2/f47b2/17

select * 
from activity a 

-- find max dates for users for records with dates after 3 months 
inner join 
(
    select username, max(acctstarttime) as max_date_start 
    from activity 
    where acctstarttime < date_sub(now(), interval 3 month) 
    group by username 
) b 
on 
    a.username = b.username 
    and a.acctstarttime = b.max_date_start 

-- find usernames who have data in the recent three months 
left join 
(
    select username, count(*) 
    from activity 
    where acctstarttime >= date_sub(now(), interval 3 month) 
    group by username 
) c 
on 
    a.username = c.username 

where 
    acctstarttime < date_sub(now(), interval 3 month) 
    -- choose users who DONT have data from recent 3 months 
    and c.username is null 

Позвольте мне знать, если вы хотите, чтобы я добавить Пояснение

+0

Извиняюсь, я исправил свой вопрос, так как существовал тип, т.е. «были» должны были быть «не были».См. Обновление в моем вопросе. –

+0

@ TheHumbleRat 'select date_sub (current_date, interval 3 month);' будет '26 июня 2014'. Поэтому должно появиться любое имя пользователя с записями после 26 июня. В дополнение к счету (ID 24) должны появляться идентификаторы 13 и 26. Это верно? – zedfoxus

+0

Нет только законопроект должен появляться как другие пользователи в таблице, у Стива и Фреда есть дата, которая находится за последние три месяца. Например, у Фреда есть запись после этой даты «07 июля 2014 года», а у Стива есть запись также после этой даты «11 июля 2014 года». Так что оба были активны в течение последних трех месяцев. Однако Билл не имеет даты начала, которая происходит в течение последних трех месяцев, и поэтому это то, что мне нужно будет видеть, людей, которые не были активны в течение последних трех месяцев. –

0

Попробуйте это:

select t.* 
    from radacct t 
    join ( 
     select ra.username, max(ra.acctstarttime) as acctstarttime 
      from radacct as ra 
     WHERE ra.acctstarttime < DATE_SUB(now(), interval 3 month) 
     ) s on t.username = s.username and t.acctstarttime = s.acctstarttime 

SQLFiddle

+0

К сожалению, это не дает мне никакого результата. У меня есть одна запись, у которой не было начальной даты в течение последнего месяца, я изменил дату, чтобы показать неделю, а запись не показывается. –

+0

@ TheHumbleRat посмотрите на [это] (http://sqlfiddle.com/#!2/2e60d/3), какая строка вам нужна? – zaratustra

+0

См. Мои обновленные комментарии. –

Смежные вопросы