2016-06-25 13 views
0

ich dies in Funken tueWie ganze Zeilen wählen, basierend auf verschiedene Spalten

cityId PhysicalAddress  EmailAddress   ..many other columns of other meta info... 
1  b st     [email protected] 
1  b st     [email protected] <- some rows can be entirely duplicates 
1  a avenue    [email protected] 
2  c square    [email protected] 
2  d blvd    [email protected] 

Es gibt keinen Primärschlüssel für diese Tabelle und ich mag, basierend auf jeder einzelnen cityId eine zufällige Reihe greifen

z.B Dies ist eine korrekte Antwort

z.B. Dies ist auch eine richtige Antwort

cityId PhysicalAddress  EmailAddress  ..many other columns 
1  a avenue    [email protected] 
2  c square    [email protected] 

Eine Möglichkeit, dass in den Sinn kommt, ist eine group by zu verwenden. Dies erfordert jedoch, dass ich eine Aggregatfunktion für die andere Spalte verwende. (wie min()). Hingegen möchte ich nur eine ganze Reihe herausziehen (egal welche).

Antwort

0
;WITH CTE AS 
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY cityId ORDER BY cityId) AS RN 
    FROM [TABLE_NAME] 
) SELECT * FROM CTE WHERE RN = 1 
0

Ich habe SQL Server 2008 R2, sondern haben versucht, Wege zu finden, die auf anderen DBMS funktionieren würde.

create table contacts(cityId int, PhysicalAddress varchar(max), EmailAddress varchar(max)) 

delete contacts 
insert contacts(cityId, PhysicalAddress, EmailAddress) /** ..many other columns of other meta info... */ 
values 
    (1, 'b st', '[email protected]') 
, (1, 'b st', '[email protected]')      /* some rows can be entirely duplicates */ 
, (1, 'a avenue', '[email protected]') 
, (2, 'c square', '[email protected]') 
, (2, 'd blvd', '[email protected]') 
, (3, 'e circuit', '[email protected]') 

-- using row_number() 

with c as (
     select *, row_number() over (partition by cityId order by cityId) as seqnum 
     from contacts 
    ) 
    select * from c 
    where seqnum = 1; 


-- Add a new identity column 

alter table contacts 
    add id int identity(1,1) 

select * from contacts where id in (select min(id) from contacts group by cityID) 

-- Variation: Create a copy into a temp table and add an identity column 
-- Note: It may not be possible to modify original table 

select * into #contacts from contacts 
alter table #contacts 
    add id int identity(1,1) 
select * from #contacts where id in (select min(id) from #contacts group by cityID) 

Ich habe auch versucht, eine berechnete Spalte newid() verwenden, aber meine Aufregung war kurzlebig, denn wenn man die Tabelle mit sich selbst verbinden oder eine Unterabfrage für die Tabelle verwenden, die berechnete Spalte für jede SELECT neu berechnet, so dass hat nicht funktioniert. Sie können diese berechnete Spalte nicht PERSISTED machen - das ist nicht für nicht-deterministische Ausdrücke wie newid() erlaubt, die jedes Mal, wenn sie für eine bestimmte Zeile aufgerufen wird, etwas anderes zurückgibt.

Verwandte Themen