tags:

views:

821

answers:

15

I need to return a list of record id's from a table that may/may not have multiple entries with that record id on the same date. The same date criteria is key - if a record has three entries on 09/10/2008, then I need all three returned. If the record only has one entry on 09/12/2008, then I don't need it.

Thanks in advance.

+3  A: 
SELECT id, datefield, count(*) FROM tablename GROUP BY datefield
  HAVING count(*) > 1
Leigh Caldwell
This is returning all records that have a date that is shared by other records. I think he wants only those records that have multiple entries with the same date.
dbrien
A: 

group by with having is your friend:

select id, count() from records group by date having count() > 1

A: 

select id from tbl where date in (select date from tbl group by date having count(*)>1)

Manu
A: 

For matching on just the date part of a Datetime:

select * from Table
where id in (
    select alias1.id from Table alias1, Table alias2
    where alias1.id != alias2.id
        and datediff(day, alias1.date, alias2.date) = 0
)

I think. This is based on my assumption that you need them on the same day month and year, but not the same time of day, so I did not use a Group by clause. From the other posts it looks like I could have more cleverly used a Having clause. Can you use a having or group by on a datediff expression?

Kevin Conner
A: 

If I understand your question correctly you could do something similar to:

select
     recordID
from
    tablewithrecords as a
    left join (
        select
          count(recordID) as recordcount
        from
          tblwithrecords
        where
          recorddate='9/10/08'
     ) as b on a.recordID=b.recordID
where
     b.recordcount>1
Travis
A: 

http://www.sql-server-performance.com/articles/dba/delete_duplicates_p1.aspx will get you going. Also, http://en.allexperts.com/q/MS-SQL-1450/2008/8/SQL-query-fetch-duplicate.htm

I found these by searching Google for 'sql duplicate data'. You'll see this isn't an unusual problem.

JBB
A: 
SELECT * FROM the_table WHERE ROW(record_id,date) IN 
  ( SELECT record_id, date FROM the_table 
    GROUP BY record_id, date WHERE COUNT(*) > 1 )
Sparr
A: 

Since you mentioned needing all three records, I am assuming you want the data as well. If you just need the id's, you can just use the group by query. To return the data, just join to that as a subquery

select * from table
inner join (
     select id, date
     from table 
     group by id, date 
     having count(*) > 1) grouped 
       on table.id = grouped.id and table.date = grouped.date
Scott Nichols
A: 

I'm not sure I understood your question, but maybe you want something like this:

SELECT id, COUNT(*) AS same_date FROM foo GROUP BY id, date HAVING same_date = 3;

This is just written from my mind and not tested in any way. Read the GROUP BY and HAVING section here. If this is not what you meant, please ignore this answer.

jkramer
A: 

Note that there's some extra processing necessary if you're using a SQL DateTime field. If you've got that extra time data in there, then you can't just use that column as-is. You've got to normalize the DateTime to a single value for all records contained within the day.

In SQL Server here's a little trick to do that:

SELECT CAST(FLOOR(CAST(CURRENT_TIMESTAMP AS float)) AS DATETIME)

You cast the DateTime into a float, which represents the Date as the integer portion and the Time as the fraction of a day that's passed. Chop off that decimal portion, then cast that back to a DateTime, and you've got midnight at the beginning of that day.

Chris Wuestefeld
A: 
SELECT id, count(*)
INTO #tmp
FROM tablename
WHERE date = @date
GROUP BY id
HAVING count(*) > 1

SELECT *
FROM tablename t
WHERE EXISTS (SELECT 1 FROM #tmp WHERE id = t.id)

DROP TABLE tablename
Eduardo Campañó
A: 

Without knowing the exact structure of your tables or what type of database you're using it's hard to answer. However if you're using MS SQL and if you have a true date/time field that has different times that the records were entered on the same date then something like this should work:

select record_id, 
       convert(varchar, date_created, 101) as log date, 
       count(distinct date_created) as num_of_entries
from record_log_table
group by convert(varchar, date_created, 101), record_id
having count(distinct date_created) > 1

Hope this helps.

Dave Lievense
+1  A: 

The top post (Leigh Caldwell) will not return duplicate records and needs to be down modded. It will identify the duplicate keys. Furthermore, it will not work if your database doesn't allows the group by to not include all select fields (many do not).

If your date field includes a time stamp then you'll need to truncate that out using one of the methods documented above ( I prefer: dateadd(dd,0, datediff(dd,0,@DateTime)) ).

I think Scott Nichols gave the correct answer and here's a script to prove it:

declare @duplicates table (
id int,
datestamp datetime,
ipsum varchar(200))

insert into @duplicates (id,datestamp,ipsum) values (1,'9/12/2008','ipsum primis in faucibus')
insert into @duplicates (id,datestamp,ipsum) values (1,'9/12/2008','Vivamus consectetuer. ')
insert into @duplicates (id,datestamp,ipsum) values (2,'9/12/2008','condimentum posuere, quam.')
insert into @duplicates (id,datestamp,ipsum) values (2,'9/13/2008','Donec eu sapien vel dui')
insert into @duplicates (id,datestamp,ipsum) values (3,'9/12/2008','In velit nulla, faucibus sed')

select a.* from @duplicates a
inner join (select id,datestamp, count(1) as number
              from @duplicates
          group by id,datestamp
            having count(1) > 1) b
       on (a.id = b.id and a.datestamp = b.datestamp)
TrickyNixon
A: 
SELECT RecordID
FROM aTable
WHERE SameDate IN
    (SELECT SameDate
    FROM aTable
    GROUP BY SameDate
    HAVING COUNT(SameDate) > 1)
A: 

TrickyNixon writes;

The top post (Leigh Caldwell) will not return duplicate records and needs to be down modded.

Yet the question doesn't ask about duplicate records. It asks about duplicate record-ids on the same date...

GROUP-BY,HAVING seems good to me. I've used it in production before.

.

Something to watch out for:

SELECT ... FROM ... GROUP BY ... HAVING count(*)>1

Will, on most database systems, run in O(NlogN) time. It's a good solution. (Select is O(N), sort is O(NlogN), group by is O(N), having is O(N) -- Worse case. Best case, date is indexed and the sort operation is more efficient.)

.

Select ... from ..., .... where a.data = b.date

Granted only idiots do a Cartesian join. But you're looking at O(N^2) time. For some databases, this also creates a "temporary" table. It's all insignificant when your table has only 10 rows. But it's gonna hurt when that table grows!

Ob link: http://en.wikipedia.org/wiki/Join_(SQL)