2015-12-16 4 views
6

Hier ist die Tabelle:Wie in einer Reihe mit drei Siegen bekommen

([TeamA],[TeamB],[Win],[date]) 

('KKR','HYD','KKR',1), 
('KKR','MUM','MUM',2), 
('RCB','HYD','HYD',3), 
('DEL','PUB','PUB',4), 
('RR','PUB','RR',4), 
('RR','DEL','RR',5), 
('RCB','CSK','CSK',6), 
('RR','CSK','RR',7), 
('CSK','MUM','MUM',7), 
('MUM','DEL','MUM',8), 
('HYD','PUNE','PUNE',9), 
('PUB','DEL','DEL',9), 
('KKR','DEL','KKR',10), 
('KKR','RCB','KKR',10) 

Die erforderliche Antwort sollte die Teams sein, die drei in einer Reihe und die Zählung gewinnen. Hier für zB RR und MUM gewinnen einmal 3 in Folge. KKR hat 3 Siege aber wenn wir die Datumsspalte ist es nicht 3 in einer Reihe damit KKR sehen nicht in der Antwort sein sollten und die Ausgabe sollte

RR 1 
MUM 1 
+1

ist Was ist Ihr dbms, MySQL oder SQL Server? – HoneyBadger

+0

'Mysql' oder' SQL-server'? Was hast du bisher versucht? – Jens

+0

Ich bin mit MS SQL Server 14 Geige –

Antwort

3

Mein Ansatz sein (wahrscheinlich kann es in sauberen Weise erfolgen) :

WITH cte AS 
(
    SELECT TeamA AS team FROM #tab 
    UNION 
    SELECT TeamB FROM #tab 
), cte2 AS 
(
    SELECT c.team 
     ,[opponent] = CASE WHEN c.team = t.teamA THEN t.teamB ELSE t.teamA END 
     ,t.[win] 
     ,t.[day] 
     ,[is_winner] = CASE WHEN c.team = t.[win] THEN 1 ELSE 0 END 
    FROM cte c 
    JOIN #tab t 
    ON c.team = t.teamA 
    OR c.team = t.teamB 
), cte3 AS 
(
    SELECT team, [day], [is_winner], 
    r = ROW_NUMBER() OVER (PARTITION BY team ORDER BY [day]) 
    FROM cte2 
), cte4 AS 
(
    SELECT team, Length = MAX(r) - MIN(r) + 1 
    FROM (SELECT team, r 
      ,rn=r-ROW_NUMBER() OVER (PARTITION BY team ORDER BY r) 
     FROM cte3 
     WHERE is_winner = 1) a 
    GROUP BY team, rn 
) 
SELECT team, SUM(Length/3) AS [Number_of_hat_tricks] 
FROM cte4 
WHERE Length >= 3 
GROUP BY team; 

LiveDemo

Ausgang:

╔══════╦══════════════════════╗ 
║ team ║ Number_of_hat_tricks ║ 
╠══════╬══════════════════════╣ 
║ MUM ║     1 ║ 
║ RR ║     1 ║ 
╚══════╩══════════════════════╝ 

Wie es funktioniert:

  • CTE - bekommen alle Teams
  • CTE2 - für jedes Team Gegner finden und prüfen, ob Team gewinnt
  • cte3 - fügen consequitive Zahlen
  • cte4 - berechnen Länge jede Insel
  • final - erhalten, die Insel> = 3 und sUM sie (ganzzahlige Division ist zum Zählen 6 Siege in Reihen als 2 und 9 in Zeilen als 3, ...)

Ein letzter Gedanke:

Wert in in letzten Spalt mit dem gleichen Team, einzigartig sein:

('RR','CSK','RR',7) 
('CSK','MUM','MUM',7) 

CSK vs RR - 7 
CSK vs MUM - 7 

mit aktuellen Daten unmöglich ist, sie in stabiler Weise zu sortieren. So sollte es Datum mit Uhrzeit sein Teil:

CSK vs RR 2015-12-07 10:00 
CSK vs MUM 2015-12-07 21:00  -- now we know that it is the second match 
+1

ging durch Ihr Profil auf SO. 22.5 K Punkte in 5 Monaten! Du bist klasse! – SouravA

+1

Danke, mein Junge! das war eine super schnelle Antwort und es funktioniert sehr gut. Ich habe eine kürzere Version geschrieben, da ich nicht viele Konzepte kannte. Ich teile meine Version –

1

Lücken und Inseln. Berechnen Sie die Länge jeder Insel. Endgültige Zählung ist die Länge der Insel dividiert durch 3 (ganzzahlige Division, Verwerfungsbruchteil).

Ich habe einige Zeilen (Teams A und B) 4 Siege von A zu veranschaulichen, dann 7 Siege von B, dann 4 Siege von A wieder, die beide in Endzahl von 2 und 2 für A und B führt.

Beispieldaten

DECLARE @T TABLE (TeamA varchar(50), TeamB varchar(50), Win varchar(50), dt int); 

INSERT INTO @T (TeamA, TeamB, Win, dt) VALUES 
('KKR','HYD','KKR',1), 
('KKR','MUM','MUM',2), 
('RCB','HYD','HYD',3), 
('DEL','PUB','PUB',4), 
('RR','PUB','RR',4), 
('RR','DEL','RR',5), 
('RCB','CSK','CSK',6), 
('RR','CSK','RR',7), 
('CSK','MUM','MUM',7), 
('MUM','DEL','MUM',8), 
('HYD','PUNE','PUNE',9), 
('PUB','DEL','DEL',9), 
('KKR','DEL','KKR',10), 
('KKR','RCB','KKR',10), 

('A','B','A',11), 
('A','B','A',12), 
('A','B','A',13), 
('A','B','A',14), 

('A','B','B',15), 
('A','B','B',16), 
('A','B','B',17), 
('A','B','B',18), 
('A','B','B',19), 
('A','B','B',20), 
('A','B','B',21), 

('A','B','A',22), 
('A','B','A',23), 
('A','B','A',24), 
('A','B','A',25); 

Abfrage

Normalerweise würden Sie eine Liste der Teams in einer separaten Tabelle haben, hier habe ich es in einem CTE_Teams bauen. CTE_Counts hat die Nummer 3-wins-in-a-row für jede aufeinanderfolgende Siegesserie. Da es für ein Team mehrere Gewinnsträhne geben kann (siehe Team A), wird dies weiter zusammengefasst.Teams können in beliebiger Reihenfolge in den Spalten TeamA und TeamB aufgeführt werden, so dass in der WHERE innerhalb der CROSS APPLY ein OR zur Erfassung beider Varianten steht.

Wählen Sie also für jedes Team nur die Zeilen aus, die für dieses Team relevant sind. Dies geschieht durch CROSS APPLY.

Dann klassische durch Nummerierung der Zeilen zweimal mit unterschiedlicher Partitionierung. Unterschiede in den Zeilennummern ergeben die Gruppen (Inseln und Lücken).

Filter WHERE CTE_Teams.Team = CA.Win lässt nur Inseln der Siegerteams.

Gruppierung nach CTE_Teams.Team gibt die Größe der Insel an, d. H. Anzahl der Gewinne in einer Reihe.

Abfrage funktioniert in SQL Server 2008.

WITH 
CTE_Teams 
AS 
(
    SELECT T.TeamA AS Team 
    FROM @T AS T 

    UNION -- sic! not ALL 

    SELECT T.TeamB AS Team 
    FROM @T AS T 
) 
,CTE_Counts 
AS 
(
    SELECT 
     CTE_Teams.Team 
     --,CA.Win 
     --,rn1 - rn2 AS GroupNumber 
     --,COUNT(*) AS GroupSize 
     ,COUNT(*)/3 AS FinalCount 
    FROM 
     CTE_Teams 
     CROSS APPLY 
     (
      SELECT 
       T.Win 
       ,T.dt 
       ,ROW_NUMBER() OVER (PARTITION BY CTE_Teams.Team 
        ORDER BY T.dt, T.TeamA, T.TeamB) AS rn1 
       ,ROW_NUMBER() OVER (PARTITION BY CTE_Teams.Team, T.Win 
        ORDER BY T.dt, T.TeamA, T.TeamB) AS rn2 
      FROM @T AS T 
      WHERE 
       T.TeamA = CTE_Teams.Team 
       OR T.TeamB = CTE_Teams.Team 
     ) AS CA 
    WHERE 
     CTE_Teams.Team = CA.Win 
    GROUP BY 
     CTE_Teams.Team 
     ,CA.Win 
     ,rn1 - rn2 
    HAVING COUNT(*)/3 > 0 
) 
SELECT 
    CTE_Counts.Team 
    ,SUM(CTE_Counts.FinalCount) AS FinalCount 
FROM CTE_Counts 
GROUP BY CTE_Counts.Team 
ORDER BY CTE_Counts.Team; 

Ergebnis

+------+------------+ 
| Team | FinalCount | 
+------+------------+ 
| A |   2 | 
| B |   2 | 
| MUM |   1 | 
| RR |   1 | 
+------+------------+ 

SQL Fiddle

+0

danke Mate. vielen dank –

1

Eine weitere Möglichkeit, dies zu lösen, ohne die Verwendung von CTE:

create table #a 
(
teama varchar(10), teamb varchar(10), win varchar(10), dat int) 

insert into #a 
values 
('KKR','HYD','KKR',1), 
('KKR','MUM','MUM',2), 
('RCB','HYD','HYD',3), 
('DEL','PUB','PUB',4), 
('RR','PUB','RR',4), 
('RR','DEL','RR',5), 
('RCB','CSK','CSK',6), 
('RR','CSK','RR',7), 
('CSK','MUM','MUM',7), 
('MUM','DEL','MUM',8), 
('HYD','PUNE','PUNE',9), 
('PUB','DEL','DEL',9), 
('KKR','DEL','KKR',10), 
('KKR','RCB','KKR',10); 

select 
team, 
win, 
row_number() over (partition by team order by dat) matchnum 
into #res 
    from 
    (
    select teamA team, case when teamA = win then 1 else 0 end as win, dat 
    from #a 
    union all 
    select teamB team, case when teamB = win then 1 else 0 end , dat 
    from #a 
    )A 
order by team,dat 


select 
    match1.team, count(*)/3 + 1 cntHatricks 
from #res match1 join #res match2 
    on match1.team = match2.team and match2.matchnum = match1.matchnum+1 
join #res match3 on match1.team = match3.team and match3.matchnum = match1.matchnum+2 
where 
    match1.win = 1 and match2.win = 1 and match3.win = 1    
    group by match1.team 

OUTPUT

+------+-------------+ 
| Team | cntHatricks | 
+------+-------------+ 
| MUM |   1 | 
| RR |   1 | 
+------+-------------+ 
+0

vielen dank sourav –

1

versuchen, diese einfache Abfrage

select tm,sum(case when win=tm then 1 else 0 end)/3 hattrick from @a a 
inner join (select teama tm from @a union select teamb from @a) t on a.win=t.tm 
group by tm 
having count(distinct dat)>2 

Daten

declare @a table 
(teama varchar(10), teamb varchar(10), win varchar(10), dat int) 
insert into @a 
values 
('KKR','HYD','KKR',1), 
('KKR','MUM','MUM',2), 
('RCB','HYD','HYD',3), 
('DEL','PUB','PUB',4), 
('RR','PUB','RR',4), 
('RR','DEL','RR',5), 
('RCB','CSK','CSK',6), 
('RR','CSK','RR',7), 
('CSK','MUM','MUM',7), 
('MUM','DEL','MUM',8), 
('HYD','PUNE','PUNE',9), 
('PUB','DEL','DEL',9), 
('KKR','DEL','KKR',10), 
('KKR','RCB','KKR',10) 

;

0

mit abc als (wählen , Fall teama wenn win dann TeamB sonst teama Ende von ipl verlieren) (wählen b.win, count (Hatrick)/3 als Nummer von ipl b join (wählen a.win zählen () als Hatrick von ipl Join ipl b auf a.win = b.win
wo a.day < b.day und a.day> all (abc.day
von Abc verbinden ipl wählen a auf a.win = abc.lose
WHERE abc.lose = b.win und abc.day < b.day)
Gruppe von a.wi n) d auf b.win = d.win
wo Hatrick> = 3 Gruppe von b.win)

Hallo Leute, ich diese Version verwendet haben. in dieser Lassen Sie mich wissen, ob es einen Glitch

Verwandte Themen