2 бағаннан артық санды сұрау

Мен екі команда бір-біріне қаншалықты жиі ойнайтындығын көрсететін sql сұрауын жазуға тырысамын.

Id | Team1 | Team2 | Date 
1  |   A   |   B   | 25/5/11
2  |   B   |   A   | 26/5/11
3  |   A   |   C   | 27/5/11
4  |   C   |   B   | 28/5/11
5  |   A   |   B   | 28/5/11

нәтиже:

A vs B => 3
A vs C => 1
C vs B => 1 

A-B және B-A-ді әртүрлі санау - бұл оңай сұрау. Бірақ оларды біріктіруге бола алмаймын.

Кез келген ұсыныстар?

6
Сіз қандай SQL нұсқасын пайдаланасыз?
қосылды автор leoinfo, көзі
Командалық аттар ештеңе болмауы мүмкін. Мен тезірек жазу үшін А және В-ды қолдандым.
қосылды автор Sorskoot, көзі
Бұл жағдайда MySql-ті менің тірі дерекқорым үшін пайдаланамын ...
қосылды автор Sorskoot, көзі
әр топты көрсететін нөмір бар ма? яғни командалық кестеден ме?
қосылды автор galchen, көзі

4 жауаптар

Топтарды топтас бұрын топтарды қайта реттеу үшін қосалқы сұрауды қолдандым.

SELECT first_team, second_team, count(*)
FROM (
    SELECT 
        CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END AS first_team,
        CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END AS second_team
    FROM table
) a
GROUP BY first_team, second_team;
6
қосылды
Бұл жұмыс істейді, бірақ ол индекстерді мүлдем пайдаланбайды, сондықтан сізде көптеген командалар болса, менің жауапымды пайдаланады.
қосылды автор Ariel, көзі
SELECT Team1, Team2, SUM(num) FROM (
   SELECT Team1, Team2, COUNT(*) num
   FROM table_name
   GROUP BY Team1, Team2
  UNION ALL
   SELECT Team2, Team1, COUNT(*) num
   FROM table_name
   GROUP BY Team2, Team1
) combined
WHERE Team1 < Team2
GROUP BY Team1, Team2

Өңдеу: Қажет кезде кері топтарға жаңартылған.

Ескерту: Бұл басқа жауаптарда берілген CASE бағдарламасын пайдаланатын нұсқаларға қарағанда жылдамырақ іске қосылады, себебі ол индекстерді толық пайдалануды қамтамасыз етеді.

Edit2: Қайда индекстермен тезірек орын ауыстырды.

5
қосылды
@Ariel - Менің ойымша серверге артық жүктемені жібердіңіз. Менің лауазымыма қарап, «Стиль 4» деп аталатын бөлімді тексеріп көріңіз. Жоспардың негізінде, бұл шамамен 60% тезірек болуы керек.
қосылды автор leoinfo, көзі
@Shark Ah, бұл жіберіп. Мәселе жоқ, менің жауапымды жаңартты.
қосылды автор Ariel, көзі
@Sorskoot Екі индекске қойыңыз: Team1, Team2 және Team2, Team1 бойынша екінші индекс
қосылды автор Ariel, көзі
Мен индекстермен жылдамырақ болу үшін оны редакцияладым. where шын мәнінде міндетті емес - егер сіз оны тастасаңыз, әр топты екі рет алсаңыз болады - бұл сізге пайдалы болуы мүмкін, өйткені сіз тек Team1 осы команда үшін екі бағанды ​​да тексерудің орнына нақты команда.
қосылды автор Ariel, көзі
@leoinfo бұл сіздің деректеріңіз аз болғандықтан жылдамырақ. Дерекқорды әр жолды нақты сұрыптауға, топтауға және санауға мәжбүрлейді. Менімен бірге индекске бару керек және индекстегі бірдей парақтардың санын тікелей алу керек, оларды нақты санаудың қажеті жоқ, оларды да сұрыптау немесе топтастырудың қажеті жоқ - жай ғана оны индексі.
қосылды автор Ariel, көзі
Бұл дәл менің нүкте ... :)
қосылды автор Sorskoot, көзі
Кесте өте үлкен болуы мүмкін ... Сондықтан көрсеткіштерді пайдалану қажет болуы мүмкін ... Спасибо ..
қосылды автор Sorskoot, көзі
Бұл дұрыс нәтиже бермейді. Бұл сұрауда A -> B және B -> A арасындағы айырмашылық бар. ОС-Б-А-мен бірге А-Б-ны іздейді.
қосылды автор user596075, көзі
@Ariel Жақсы жұмыс істейді! +1
қосылды автор user596075, көзі

Сіздің мақсатыңызға жетудің бірнеше жолы бар:

SELECT Teams, Games = COUNT(*) FROM 
(
  SELECT 
    Teams = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END + ' vs ' +
            CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END
  FROM MY_TABLE 
) AS T
GROUP BY Teams

НЕМЕСЕ, SQL 2005/2008 пайдалансаңыз

;WITH T AS (
  SELECT 
    Teams = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END + ' vs ' +
            CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END
  FROM MY_TABLE 
)
SELECT Teams, Games = COUNT(*) FROM T GROUP BY Teams

Жоғарыдағы екеуі де сізге бірдей нәтиже береді

/*
Teams     Games
-------|------
A vs B  3
A vs C  1
B vs C  1
*/

Мынамен ойнауға болатын сценарий:

/* TEST DATA */
DECLARE @t AS TABLE ( ID INT, Team1 CHAR(1), Team2 CHAR(1), playdate [DATETIME] )
INSERT INTO @t (Team1 , Team2 , playdate)
          SELECT 'A' , 'B', '20110525'
UNION ALL SELECT 'B' , 'A', '20110526'    
UNION ALL SELECT 'A' , 'C', '20110527'    
UNION ALL SELECT 'C' , 'B', '20110528'    
UNION ALL SELECT 'A' , 'B', '20110528'    


/* STYLE 1 */    
;WITH T AS (
  SELECT 
    Teams = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END + ' vs ' +
            CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END
  FROM @t 
)
SELECT Teams, Games = COUNT(*) FROM T GROUP BY Teams

/* STYLE 2 */
SELECT Teams, Games = COUNT(*) FROM 
(
  SELECT 
    Teams = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END + ' vs ' +
            CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END
  FROM @t 
) AS T
GROUP BY Teams

/ * НЕМЕСЕ бұл бағанды ​​* /,

/* STYLE 3 */    
;WITH T AS (
  SELECT 
      Team1 = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END 
    , Team2 = CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END
  FROM @t 
)
SELECT Team1 , Team2, Games = COUNT(*) FROM T GROUP BY Team1 , Team2

/* STYLE 4 */
SELECT Team1 , Team2, Games = COUNT(*) FROM 
(
  SELECT 
      Team1 = CASE WHEN Team1 < Team2 THEN Team1 ELSE Team2 END 
    , Team2 = CASE WHEN Team1 < Team2 THEN Team2 ELSE Team1 END
  FROM @t 
) AS T
GROUP BY Team1 , Team2
1
қосылды
SELECT 
  (CASE WHEN Team1Team2 THEN Team1 ELSE Team2) Team2,
  COUNT(*)  cnt
FROM <table> 
GROUP BY 
  (CASE WHEN Team1Team2 THEN Team1 ELSE Team2) Team2
1
қосылды