2017-02-22 11 views
0

ich in TSQL folgenden Tabelle haben (es gibt auch andere Spalten zu, aber keine Identitätsspalte oder Primärschlüsselspalte):TSQL: Finden Paar-Sequenz in einer Tabelle

Oid Cid 
    1 a 
    1 b 
    2 f 
    3 c 
    4 f 
    5 a 
    5 b 
    6 f 
    6 g 
    7 f 

So in obigen Beispiel würde Ich mag an hervorzuheben, dass folgende Oid Duplikat sind, wenn sie bei Cid Spaltenwerte als „-Paare“ suchen:

Oid: 
1 (1 matches Oid: 5) 
2 (2 matches Oid: 4 and 7) 

Bitte beachten Sie das Oid 2 Spiel nicht enthalten Oid 6, da das Paar von 6 hat Buchstaben ‚G‘ als auch.

Ist es möglich, eine Abfrage ohne While-Schleife zu erstellen, um die "Oid" wie oben zu markieren? zusammen mit wie viele andere Übereinstimmungen zählen in der Datenbank existieren? Ich versuche, die Muster innerhalb des Datensatzes zu diesen beiden Spalten zu finden. Vielen Dank im Voraus.

+0

Bitte beachten Sie, dass es das Paar passenden, das ich nicht das Individuum tun müssen Buchstabenabgleich. Also in der gewünschten Ergebnismenge, für Oid = 2 sollte es keinen Buchstabenvergleich für Oid 6 enthalten. Da es auch den Buchstaben 'G' hat. Hoffe, dies wird klar – hss

Antwort

2

ist hier ein ausgearbeitetes Beispiel - siehe Kommentar zur Erklärung:

--First set up your data in a temp table 
declare @oidcid table (Oid int, Cid char(1)); 
insert into @oidcid values 
(1,'a'), 
(1,'b'), 
(2,'f'), 
(3,'c'), 
(4,'f'), 
(5,'a'), 
(5,'b'), 
(6,'f'), 
(6,'g'), 
(7,'f'); 

--This cte gets a table with all of the cids in order, for each oid 
with cte as (
    select distinct Oid, (select Cid + ',' from @oidcid i2 
          where i2.Oid = i.Oid order by Cid 
          for xml path('')) Cids 
    from @oidcid i 
) 
select Oid, cte.Cids 
from cte 
inner join ( 
    -- Here we get just the lists of cids that appear more than once 
    select Cids, Count(Oid) as OidCount 
    from cte group by Cids 
    having Count(Oid) > 1) as gcte on cte.Cids = gcte.Cids 
-- And when we list them, we are showing the oids with duplicate cids next to each other 
Order by cte.Cids 
0
select o1.Cid, o1.Oid, o2.Oid 
    , count(*) + 1 over (partition by o1.Cid) as [cnt] 
from table o1 
join table o2 
    on o1.Cid = o2.Cid 
and o1.Oid < o2.Oid 
order by o1.Cid, o1.Oid, o2.Oid 
+0

Vielen Dank für die Reaktion auf @ Paparazzi. Diese Lösung bietet keine richtige Antwort für Oid 2. Anstatt zu sagen, dass es "F" 3 Mal entspricht (für 2, 4 und 7, wenn es 2 enthält), sagt es, dass es 4 Mal übereinstimmt (für 2, 4, 6, 7). Es ist die Paarung, die ich tun muss, nicht die individuelle Übereinstimmung. Da 6 'F' und 'G' hat, sollte es nicht ausgewählt werden. Sorry, wenn der Beitrag nicht klar war – hss

0

Vielleicht wie dies dann:

WITH CTE AS 
(
    SELECT Cid, oid 
    ,ROW_NUMBER() OVER (PARTITION BY cid ORDER BY cid) AS RN 
    ,SUM(1) OVER (PARTITION BY oid) AS maxRow2 
    ,SUM(1) OVER (PARTITION BY cid) AS maxRow 
    FROM oid 
) 
SELECT * FROM CTE WHERE maxRow != 1 AND maxRow2 = 1 
ORDER BY oid 
+0

Vielen Dank für Ihre Antwort @ Owain-Esau. Diese Lösung bietet keine richtige Antwort für Oid 2. Anstatt zu sagen, dass es "F" 3 Mal entspricht (für 2, 4 und 7, wenn es 2 enthält), sagt es, dass es 4 Mal übereinstimmt (für 2, 4, 6, 7). Es ist die Paarung, die ich tun muss, nicht die individuelle Übereinstimmung. Da 6 'F' und 'G' hat, sollte es nicht ausgewählt werden. Entschuldigung, wenn der Beitrag nicht klar war – hss

Verwandte Themen