【问题标题】:SELECT DISTINCT from multiple columns从多列中选择 DISTINCT
【发布时间】:2012-04-26 07:17:52
【问题描述】:

这是一个有点复杂的查询,但我有一个斯诺克比赛数据库,我正在尝试生成谁打过比赛并赢得了最多决定性的比赛的统计数据(如果你不担心规则,请不要担心了解游戏)。

表:

ID player1  player2   bestOf     player1Score      player2Score
1   1           2          9          5                   0
2   2           1          9          5                   4
3   1           2          9          5                   4
4   2           1          9          4                   5

我正在尝试做的事情如下:

SELECT COUNT(*) AS played, DISTINCT(player1,player2) AS playerID 
FROM matches 
WHERE (player1Score=BestOf / 2 + 0.5 AND player2Score=BestOf / 2 - 0.5) 
GROUP BY playerID

上面的查询不起作用,因为我相信 DISTINCT 不支持多列。我从上表中寻找的结果是:

playerID played  won
1           3      2
2           3      1

表格中的第一行不显示,因为它不是最后一帧。

我尝试过以下变体:

SELECT GROUP(player1,player2)
SELECT player1 + player2 AS playerID, select DISTINCT(playerID)
SELECT (player1 + player2) AS playerID GROUP BY playerID

还有一些其他的。任何提示将不胜感激!

【问题讨论】:

  • 您可能正在寻找CONCAT()dev.mysql.com/doc/refman/5.5/en/…
  • 嗯.. 讨厌的设计。尝试学习数据库规范化。别担心,不是regular expressions,你可以很容易地学习它:-)
  • player1 和 player 怎么可能只玩三场比赛。根据样本数据,看起来他们已经打了四场比赛。玩家 1 赢了 3 局,玩家 2 赢了 1 局。
  • @Romil 我认为“决定帧”的含义是最后一场比赛完全决定谁会赢得比赛的比赛。第一局不是这样,但接下来的3局,最后一局决定了比赛的胜负。
  • adi92 是正确的,不幸的是 CONCAT() 似乎不起作用。

标签: mysql select distinct


【解决方案1】:

我实际上并没有你的表,所以我的 sql 可能有很多语法错误。但希望我能理解这个总体思路。 我们可以计算player1获胜的决胜局列表,并将其与player2获胜的决胜局列表合并。只要我们将获胜者的列名重命名为相同的字符串('player'),这些表的联合应该会产生一个表,标出每个人获胜的次数。

select player, count(*) as num_won from ((select player1 as player from matches where player1Score - player2Score = 1) union (select player2 as player from matches where player2Score - player1Score = 1));

这应该为您提供从每个玩家的 id 到他们获胜次数的映射。

然后考虑

select player, count(*) as num_played from ((select player1 as player from matches where abs(player1Score - player2Score) = 1) union (select player2 as player from matches where abs(player2Score - player1Score) = 1));

abs 函数的使用应该可以帮助您了解每个玩家玩的决胜局游戏的数量。现在我们将这两张表结合起来得到你的最终答案

select players_table.player, players_table.num_played, winners_table.num_won from (select player, count(*) as num_won from ((select player1 as player from matches where player1Score - player2Score = 1) union (select player2 as player from matches where player2Score - player1Score = 1)) winners_table), (select player, count(*) as num_played from ((select player1 as player from matches where abs(player1Score - player2Score) = 1) union (select player2 as player from matches where abs(player2Score - player1Score) = 1)) players_table) where winners_table.player == players_table.player;

【讨论】:

  • 我试过这个,但是得到一个派生表错误,我可能会看看这个。谢谢!
  • 你能复制粘贴错误吗?您是否为创建的所有中间表提供了别名?
  • 我没有,错误是“#1248 - 每个派生表都必须有自己的别名”。我对别名不熟悉,我会四处搜索,找出如何使用它们并回复你。谢谢!
  • 对不起。我很难创建正确的 SQL 语句,而实际上在 mysql 控制台中没有你的表和一些数据。正如错误消息所说,每个中间表都必须有自己的唯一别名。基本上每个子查询都是一个中间表。我建议的方法涉及大量嵌套子查询。你需要给每个人一个别名。因此,使用其中包含 select 语句的每组括号并在其右侧添加不同的字母。没有两个字母必须匹配,所有语句无论多么嵌套,都必须在其右侧有一个字母。
  • 啊哈,我明白你的意思了。周末去试试,非常感谢adi92的帮助!
【解决方案2】:
create table temp_score
select playerid, count(*) as won 
FROM(
  Select   case  when player1score > player2score then  player1 else player2 end as playerid
    from score
    where
    (player2Score=Round(BestOf / 2 + 0.5,0) AND player1Score=round(BestOf / 2 - 0.5,0))
    or
    (player1Score=Round(BestOf / 2 + 0.5,0) AND player2Score=round(BestOf / 2 - 0.5,0))
) a
group by playerid

Select playerid,won, (Select SUM(won) from temp_score)  as TotalPlayed  from temp_score

【讨论】:

  • 我喜欢在一个查询中执行它的外观,但是我已经在 MySQL 中对其进行了测试,将 Score_Cte 替换为我的实际表名,这会给出错误:“#1064 - You have an error in your SQL 语法;查看与您的 MySQL 服务器版本相对应的手册,以获取正确的语法,以便在 'matches as (Select playerid,COUNT(*) as won from ( Select case when' at line 1" 附近使用
  • 这个答案与 MS Sql 有关。对于MySql,您可以将内部结果存储在一个表中,然后对临时表执行第二次查询以获得最终结果。
  • 据我所知,MySQL 没有 CTE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 2011-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多