2008-09-16 22 views
3

Ich muss eine Liste von Datensatz-IDs aus einer Tabelle zurückgeben, die möglicherweise mehrere Einträge mit dieser Datensatz-ID am selben Datum haben. Das gleiche Datum Kriterium ist der Schlüssel - wenn ein Datensatz hat drei Einträge am 09/10/2008, dann brauche ich alle drei zurückgegeben. Wenn der Datensatz am 09.12.2008 nur einen Eintrag hat, brauche ich ihn nicht.Liste der Datensätze mit mehreren Einträgen am selben Datum abrufen

+0

Für diese Klasse von Problem ist es eine gute Idee, das RDBMS zu spezifizieren. Oracle kann Lösungen verwenden, die SQL Server nicht kann und umgekehrt. –

Antwort

3
SELECT id, datefield, count(*) FROM tablename GROUP BY datefield 
    HAVING count(*) > 1 
+0

Dies gibt alle Datensätze zurück, deren Datum von anderen Datensätzen gemeinsam genutzt wird. Ich denke, er will nur die Datensätze, die mehrere Einträge mit demselben Datum haben. – dbrien

1

GROUP BY mit HAVING ist dein Freund:

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

Zur Anpassung an nur den Datumsteil eines 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 
) 

denke ich. Dies basiert auf meiner Annahme, dass Sie sie an demselben Tag, Monat und Jahr benötigen, aber nicht zur selben Tageszeit, also habe ich keine Group by-Klausel verwendet. Von den anderen Posts sieht es so aus, als hätte ich geschickt eine Having-Klausel verwenden können. Können Sie eine Hasting oder Gruppe mit einem datediff Ausdruck verwenden?

1

Wenn ich Ihre Frage richtig verstehe Sie etwas Ähnliches tun könnte:

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 
1
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) 
1

Da Sie erwähnten, dass Sie alle drei Datensätze benötigen, gehe ich davon aus, dass Sie die Daten ebenfalls benötigen. Wenn Sie nur die IDs benötigen, können Sie einfach die Gruppe nach Abfrage verwenden. Um die Daten zurückgeben, kommen nur zu, dass als Unterabfrage

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 
1

Ich bin nicht sicher, ob ich verstanden Ihre Frage, aber vielleicht möchten Sie etwas wie folgt aus:

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

Dies wird gerade geschrieben von meiner Geist und nicht in irgendeiner Weise getestet. Lesen Sie den Abschnitt GROUP BY und HAVING unter here. Wenn dies nicht das ist, was Sie meinten, ignorieren Sie bitte diese Antwort.

1

Beachten Sie, dass eine zusätzliche Verarbeitung erforderlich ist, wenn Sie ein SQL DateTime-Feld verwenden. Wenn Sie diese zusätzlichen Zeitdaten dort haben, dann können Sie diese Spalte nicht so verwenden, wie sie ist. Sie müssen die DateTime auf einen einzelnen Wert für alle Datensätze innerhalb des Tages normalisieren.

In SQL Server ist hier ein kleiner Trick, das zu tun:

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

Sie werfen die Datetime in einem Schwimmer, der das Datum als der ganzzahlige Teil und der Zeit als Bruchteil eines Tages darstellt, die vergangen ist. Zerhacke diesen dezimalen Teil und wirf ihn dann auf eine DateTime zurück, und du hast Mitternacht zu Beginn dieses Tages.

1
 
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 
1

Ohne die genaue Struktur Ihrer Tabellen zu kennen oder welche Art von Datenbank Sie verwenden, ist es schwer zu beantworten.Allerdings, wenn Sie MS SQL verwenden und wenn Sie ein wahres Datum/Zeit-Feld, die verschiedenen Zeiten hat, dass die Datensätze auf dem gleiche Datum eingegeben wurden dann so etwas wie dies funktionieren soll:

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 

Hoffnung, das hilft.

2

Der oberste Beitrag (Leigh Caldwell) gibt keine doppelten Datensätze zurück und muss downmodded sein. Es identifiziert die doppelten Schlüssel. Darüber hinaus wird es nicht funktionieren, wenn Ihre Datenbank nicht zulässt, dass die Gruppe alle ausgewählten Felder nicht enthält (viele nicht).

Wenn Ihr Datumsfeld einen Zeitstempel enthält, müssen Sie das mit einer der oben dokumentierten Methoden abschneiden (ich bevorzuge: dateadd (dd, 0, datediff (dd, 0, @ DateTime))).

denke ich, Scott Nichols die richtige Antwort gab und hier ist ein Skript, es zu beweisen:

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) 
2
SELECT RecordID 
FROM aTable 
WHERE SameDate IN 
    (SELECT SameDate 
    FROM aTable 
    GROUP BY SameDate 
    HAVING COUNT(SameDate) > 1) 
1

TrickyNixon schreibt;

Der oberste Beitrag (Leigh Caldwell) wird keine doppelten Datensätze zurückgeben und muss down modded sein.

Noch fragt die Frage nicht nach doppelten Datensätzen. Es fragt nach doppelten Datensatz-IDs am selben Datum ...

GROUP-BY, HAVING scheint mir gut. Ich habe es schon früher in der Produktion benutzt.

.

Etwas zu achten:

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

Will, auf den meisten Datenbanksystemen laufen in O (NlogN) Zeit. Es ist eine gute Lösung. (Auswahl ist O (N), Sortierung ist O (NlogN), Gruppierung nach ist O (N), wobei O (N) ist - schlechterer Fall. Bestes Datum wird indiziert und die Sortieroperation ist effizienter.)

.

Auswählen ... von ..., .... wo a.data = b.date

Zugegeben nur Idioten eine cartesianischen treten. Aber du schaust auf O (N^2) Zeit. Bei einigen Datenbanken wird dadurch auch eine "temporäre" Tabelle erstellt. Es ist alles unbedeutend, wenn Ihr Tisch nur 10 Zeilen hat. Aber es wird weh tun, wenn dieser Tisch wächst!

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

Verwandte Themen