【问题标题】:How to make sql query returns only in 1 row? or How to merge or combine the 2 results into 1如何使 sql 查询仅在 1 行中返回?或如何将 2 个结果合并或合并为 1
【发布时间】:2015-01-20 07:51:13
【问题描述】:

问题:

  • 如何将 2 个团队结果合并或合并为 1 个?或者
  • 如何让它只返回 1 行?

表名: series_type

id| type| description 
1 |    0| No series (Any team win 1 will be the winner)
2 |    1| Best of 3 (Any team wins 2 will be the winner else draw)
3 |    2| Best of 5 (Any team wins 3 will be the winner else draw)

表名: 团队

       ID| name 
  1848158| LV
       15| LGD

表名: 匹配项

ID| series_id | series_type | league_id | start_time |radiant_name | dire_name | radiant_win
1 |      8313 |           2 |      2096 |   xxxxxxx1 |          LV |       LGD | true 
2 |      8313 |           2 |      2096 |   xxxxxxx2 |         LGD |        LV | false
3 |      8313 |           2 |      2096 |   xxxxxxx3 |          LV |       LGD | false
4 |      8313 |           2 |      2096 |   xxxxxxx4 |          LV |       LGD | false
5 |      8313 |           2 |      2096 |   xxxxxxx5 |         LGD |        LV | false

查询:

SELECT series_id, team, SUM(Win) As Won, SUM(Loss) as Lost
FROM
( SELECT *,radiant_name as team, 
     CASE WHEN radiant_win = 1 THEN 1 ELSE 0 END as Win, 
     CASE WHEN radiant_win = 1 THEN 0 ELSE 1 END as Loss
  FROM matches
  UNION ALL
  SELECT *,dire_name as team, 
     CASE WHEN radiant_win = 0 THEN 1 ELSE 0 END as Win, 
     CASE WHEN radiant_win = 0 THEN 0 ELSE 1 END as Loss
  FROM matches
) as temp
WHERE series_id = 8313
GROUP By team
ORDER By Won, Lost DESC

结果: 当按 series_id 分组时

series_id| team| Won| Lost|
     8313|   LV|   5|    5|

结果: 分组时

series_id| team| Won| Lost|
     8313|  LGD|   2|    3|
     8313|   LV|   3|    2|

预期结果: 我需要按 series_id 分组

series_id| teamA| teamB| teamAWon| teamBWon| teamALost| teamBLost|
     8313|    LV|   LGD|        3|        2|         2|         3|

【问题讨论】:

  • 我回答了,但是您能否发布您的表格结构,并明确说明您想要的结果?另外,这个系列赛中是否有超过两支球队?还是同样的两支球队在打系列赛的每一场比赛?
  • 为什么要包含原表和结构?
  • 请再次查看。谢谢

标签: mysql sql database performance laravel-4


【解决方案1】:

我对这个问题有两个结果,一个是针对任何 sql,另一个是针对 oracle sql(因为我在其中使用了 oracle 函数)

可以在任何 sql 上运行此解决方案:-

SELECT AB.SERIES_ID,TEAMA,TEAMB ,TEAMAWON,COUNT(STC.SERIES_ID)-TEAMAWON TEAMBWON,
COUNT(STC.SERIES_ID)-TEAMAWON TEAMALOST,
COUNT(STC.SERIES_ID)-(COUNT(STC.SERIES_ID)-TEAMAWON) TEAMBLOST FROM  
(
  SELECT MA.SERIES_ID,MA.RADIANT_NAME TEAMA,MA.DIRE_NAME TEAMB ,
  COUNT(RADIANT_WIN) TEAMAWON FROM MATCHES MA,SERIES_TYPE ST
  WHERE  MA.SERIES_TYPE=ST.TYPE   
  GROUP BY MA.SERIES_ID,MA.RADIANT_NAME,DIRE_NAME
) AB, MATCHES STC 
WHERE (AB.SERIES_ID,AB.TEAMAWON) IN
  (
    SELECT SERIES_ID,MAX(RADIANT_WIN) RAD
    FROM
    (
        SELECT MA.SERIES_ID,MA.RADIANT_NAME ,COUNT(RADIANT_WIN) RADIANT_WIN 
        FROM  MATCHES MA,SERIES_TYPE ST
        WHERE  MA.SERIES_TYPE=ST.TYPE   
        GROUP BY MA.SERIES_ID,MA.RADIANT_NAME,DIRE_NAME
    )
     GROUP BY SERIES_ID
 ) AND STC.SERIES_ID=AB.SERIES_ID AND  TEAMA IN (RADIANT_NAME,DIRE_NAME)
 GROUP BY AB.SERIES_ID,TEAMA,TEAMB ,TEAMAWON;

现在我正在为使用 oracle 寻求相同结果的 oracle 人编写解决方案:-

SELECT SERIES_ID,GREATEST(RADIANT_NAME,DIRE_NAME) TEAMA,
LEAST(RADIANT_NAME,DIRE_NAME) TEAMB ,max(RADIANT_WIN) TEAMAWON,
SUM(RADIANT_WIN)-max(RADIANT_WIN) TEAMBWON,
SUM(RADIANT_WIN)-max(RADIANT_WIN) TEAMALOST,
SUM(RADIANT_WIN)-(SUM(RADIANT_WIN)-Max(RADIANT_WIN)) TEAMBLOST
FROM
(
   SELECT MA.SERIES_ID,MA.RADIANT_NAME,DIRE_NAME ,
   COUNT(RADIANT_WIN) RADIANT_WIN FROM MATCHES MA,SERIES_TYPE ST
   WHERE  MA.SERIES_TYPE=ST.TYPE 
   GROUP BY MA.SERIES_ID,MA.RADIANT_NAME,DIRE_NAME
) GROUP BY SERIES_ID,
  greatest(RADIANT_NAME,DIRE_NAME) ,least(RADIANT_NAME,DIRE_NAME);

【讨论】:

  • 错误太多。你可以使用 phpmyadmin 制作 mysql 版本吗?谢谢
  • okk 所以你在 mysql 环境中运行它.. 可能它可能无法像我在 oracle 和 sql dbms 上那样工作。我正在尝试找到任何在线 phpmyadmin 环境来工作并且会回来很快就会在这个 dbms 上查询
  • 非常感谢您抽出宝贵的时间。希望你能做到。因为我真的很需要它来优化。
  • 请看一下。 dba.stackexchange.com/questions/17921/… 这与我想要的结果相同..
【解决方案2】:

主要的复杂因素是每个团队名称可以在 radiant_name 或 dire_name 中出现 0 次或更多次。因此,将团队旋转到每个团队名称的一列中有点复杂。如果比赛有一个固定的 teamA 和 teamB 列,然后有一个列表示哪支球队光芒四射,另一列表示哪支球队获胜,那就更容易了。

这几乎肯定不是最佳的,但它似乎有效:

-- create a two-column temp table with series ID and team name, insert rows from matches
-- we'll wind up with one row per distinct radiant_name and distinct dire_name,
-- so up to 4 rows for a series
CREATE TEMPORARY TABLE IF NOT EXISTS tempteama AS
select distinct series_id, radiant_name AS team
from matches
union
select distinct series_id, dire_name AS team
from matches;

-- do this again in a second temp table, so we can join the two later
-- (MySQL doesn't like to join temp tables against themselves)
CREATE TEMPORARY TABLE IF NOT EXISTS tempteamb AS
select distinct series_id, radiant_name AS team
from matches
union
select distinct series_id, dire_name AS team
from matches;

-- join matches against the temp table to get final results
select matches.series_id, 
teamA, 
teamB, 
sum(case when (radiant_name = teamA AND radiant_win=1) OR (dire_name=teamA AND radiant_win=0) then 1 else 0 end) AS teamA_win,
sum(case when (radiant_name = teamB AND radiant_win=1) OR (dire_name=teamB AND radiant_win=0) then 1 else 0 end) AS teamB_win
from matches
join (
-- select just one row from the temp table. That gives us the combination of teams for the series.
select tempteama.series_id, tempteama.team AS teamA, tempteamb.team AS teamB
from tempteama
join tempteamb on tempteama.series_id = tempteamb.series_id and tempteama.team != tempteamb.team
limit 1
) AS teamnames on teamnames.series_id = matches.series_id
group by matches.series_id, teamA, teamB;

您可以将临时表查询作为子查询进行,但会牺牲一些可读性。

【讨论】:

  • 嘿,你能看看这个。这是主要的。 stackoverflow.com/questions/27054402/…
  • OK...对于一个特定的系列,给定的团队至少会成为辐射团队和可怕团队吗?或者有没有可能同一支球队将成为系列赛所有比赛的光芒四射的球队?
  • 比赛将被分配给每支球队随机的位置作为辐射或可怕。所以不只有 1 个团队用于夜魇和 1 个团队用于辐射。
  • 为什么返回零结果?
  • 对我来说它返回一行:'8313','LGD','LV','2','3' 也许我创建的表与您的匹配表具有不同的结构。 radiant_win 的列类型是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多