Mysql唯一记录,其中存在多个记录

时间:2014-09-26 12:58:55

标签: mysql

我正在努力使用Mysql,希望借用你的专业知识。

我相信我想要的东西可能只能使用两个选择而我还没有完成其中一个并且我正在努力解决这个问题。

我有一张这样的表:

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

我希望只从用户名栏中选择唯一的记录,即我只想要一张票据记录,我需要最近的start_date记录,前提是他们 不是最近三个月(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个月。 我已经厌倦了一些其他的组合,并尝试了双选的命令,但我目前正在打砖墙。任何帮助或推动正确的方向将非常感激。

更新

我创建了以下内容: http://sqlfiddle.com/#!2/f47b2/1

实际上,我应该只在查询应该是的时候看到1行。这将是账单的行。因为他是唯一一个在过去三个月内没有开始日期的人。我期望看到的结果如下:

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

由于这是帐单的最新开始日期,但此开始日期不在过去三个月内。希望这有助于澄清。非常感谢你的帮助。

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

这是另一个例子。如果账单的acctstartdate显示为4月条目,那么我可以在过去三个月添加我的where子句,这将给我我想要的结果。

2 个答案:

答案 0 :(得分:1)

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

我根据当前文字以两种方式查看问题:

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)

希望您可以根据自己的喜好更改这些查询。

修改

根据您的好解释,这是查询 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

如果您希望我添加说明,请告诉我

答案 1 :(得分: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