簡體   English   中英

如何在MySQL中為每個組選擇多行?

[英]How to select more than one row per group in MySQL?

這是我的桌子“puntos”:

  Equipo      Liga  Puntos
---------------------------
 At. Madrid     1     68
 Espanyol       1     64
 Barcelona      1     63
 Real Madrid    1     61
 Castellón      1     48
 Murcia         2     78
 Elche          2     70
 Sevilla        2     60
 Valladolid     2     57

我只想獲得屬性“Liga”的每個不同值的兩行,這兩個具有“Liga”組的“Puntos”組的最大值。

所以它應該返回類似的東西:

 Equipo      Liga  Puntos
---------------------------
 At. Madrid     1     68
 Espanyol       1     64
 Murcia         2     78
 Elche          2     70

我得到了該查詢的結果:

SELECT * FROM puntos GROUP BY Liga HAVING max(puntos) 
UNION
SELECT p1.Equipo, p1.Liga, max(p1.puntos) FROM puntos p1, (SELECT * FROM puntos GROUP BY Liga HAVING max(puntos) ORDER BY Liga,puntos DESC) p2
WHERE p1.Liga=p2.Liga AND p1.puntos<p2.puntos GROUP BY Liga
ORDER BY Liga,puntos DESC

但是,如果列“puntos”的選擇值相等,則該解決方案無效。

有沒有其他方法可以為任何價值做,無論是否相等?

首先,只有當Equipo在所有聯賽中都是獨一無二的時候,這個解決方案才有效。 如果不是 - 你應該添加equipoID並改為使用它。

現在,我們首先選擇每個聯賽的領導者。 然后再次創建一個具有相同選擇的聯合,只使用WHERE過濾掉我們在第一個聯合上已經獲得的團隊。 這基本上會給我們追隨者。

這是查詢:

SELECT * FROM
  (SELECT * FROM puntos ORDER BY `liga`,`puntos` DESC) `leader`
GROUP BY `liga`

UNION
SELECT * FROM
  (SELECT * FROM puntos ORDER BY `liga`,`puntos` DESC) `follower`
WHERE `follower`.`equipo` NOT IN 
  (SELECT equipo FROM
    (SELECT * FROM puntos ORDER BY `liga`,`puntos` DESC) `leader`
   GROUP BY `liga`
  )
GROUP BY `liga`
ORDER BY `liga`

獲得最大的puntos

SELECT Equipo, Liga, max(Puntos) Puntos FROM results GROUP BY Liga

然后從點移除Liga的最大值並再次獲得最大值

SELECT Equipo, Liga, max(Puntos) Puntos FROM results A 
    WHERE Puntos NOT IN 
    (SELECT max(Puntos) Puntos FROM results B 
     WHERE A.LIGA = B.LIGA 
     GROUP BY Liga)
    GROUP BY Liga

包裝整個選擇以排序列

SELECT Equipo, Liga, Puntos
FROM
(SELECT Equipo, Liga, max(Puntos) Puntos FROM results GROUP BY Liga
UNION 
SELECT Equipo, Liga, max(Puntos) Puntos FROM results A 
WHERE Puntos NOT IN 
(SELECT max(Puntos) Puntos FROM results B 
 WHERE A.LIGA = B.LIGA
 GROUP BY Liga)
GROUP BY Liga)  T
ORDER BY Liga ASC, Puntos DESC

檢查SqlFiddle

另一種選擇是使用9.4用戶定義的變量

SELECT
  `der`.`Equipo`,
  `der`.`Liga`,
  `der`.`Puntos` 
FROM (
  SELECT
    `p`.`Equipo`,
    `p`.`Liga`,
    `p`.`Puntos`,
    IF(@`prev_liga` != `p`.`Liga`,
        @`rownum` := 1,
        @`rownum` := @`rownum` + 1
    ) `rank`,
    @`prev_liga` := `p`.`Liga`
  FROM (
    SELECT
      `Equipo`,
      `Liga`,
      `Puntos`
    FROM `puntos`
    GROUP BY `Liga`, `Puntos`
    ORDER BY `Liga`, `Puntos` DESC   
  ) `p`, (SELECT
            @`rownum` := NULL,
            @`prev_liga` := 0) `r`
) `der`
WHERE `der`.`rank` <= 2
ORDER BY `der`.`Liga`, `der`.`rank`;

SQL小提琴演示

來自同一“Liga”的兩支隊伍等同於“Puntos”:

SELECT
  `der`.`Equipo`,
  `der`.`Liga`,
  `der`.`Puntos` 
FROM (
  SELECT
    `p`.`Equipo`,
    `p`.`Liga`,
    `p`.`Puntos`,
    IF(@`prev_liga` != `p`.`Liga`,
        @`rownum` := 1,
        @`rownum` := @`rownum` + 1
    ) `rank`,
    @`prev_liga` := `p`.`Liga`
  FROM (
    SELECT
      `Equipo`,
      `Liga`,
      `Puntos`
    FROM `puntos`
    ORDER BY `Liga`, `Puntos` DESC   
  ) `p`, (SELECT
            @`rownum` := NULL,
            @`prev_liga` := 0) `r`
) `der`
WHERE `der`.`rank` <= 2
ORDER BY `der`.`Liga`, `der`.`rank`;

SQL小提琴演示

嗨,我會建議這個問題的方法很少。

SET @num := 0, @liga := 0;

SELECT Equipo, Liga, Puntos
FROM (SELECT Equipo, Liga, Puntos, @num := if(@liga = Liga, @num + 1, 1) AS rowNumber,
              @liga := Liga
      FROM (SELECT Equipo, Liga, Puntos
            FROM results
            ORDER BY Liga, Puntos DESC) t1) tx
WHERE rowNumber <= 2;

這里還有SQL小提琴 ,看它是如何工作的...

在這里你可以看看我以前的一個(非常相似的答案)!

GL!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM