【问题标题】:Pivot style calculation on multiple columns多列的透视样式计算
【发布时间】:2016-04-03 14:04:53
【问题描述】:

我有一个 MySQL 表,其中包含一个用户的团队,每个用户都有一个 player1、player2 和 player3 字段。

我正在尝试从 3 个玩家列中计算所有用户中所选玩家的总数..

user1 可以选择 playerA、playerC 和 playerG。

user2 可以选择 playerE、playerF 和 playerH。

user3 可以选择 playerB、playerA 和 playerF。

user4 可以选择 playerC、playerE 和 playerA。

我可以针对每个玩家列运行一个语句,即

SELECT player1, count(*) as total from users;
SELECT player2, count(*) as total from users;
SELECT player3, count(*) as total from users; 

问题是我需要一个包罗万象的结果集,它会显示所有被选中的玩家的总数,所以我会得到如下所示的内容

player        total
playerA       3
playerB       1
playerC       2
playerE       2
playerF       2
playerG       1
playerH       1

我的表结构如下

CREATE TABLE `leaderboard_api` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `competition_id` char(3) DEFAULT NULL,
  `year` year(4) DEFAULT NULL,
  `position` int(4) DEFAULT NULL,
  `name` varchar(128) DEFAULT NULL,
  `player1_name` varchar(128) DEFAULT NULL,
  `player1_score` tinyint(11) DEFAULT NULL,
  `player2_name` varchar(128) DEFAULT NULL,
  `player2_score` tinyint(11) DEFAULT NULL,
  `player3_name` varchar(128) DEFAULT NULL,
  `player3_score` tinyint(11) DEFAULT NULL,
  `total_score` tinyint(11) DEFAULT NULL,
  `missed_cut` tinyint(1) DEFAULT NULL,
  `withdrawn` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

当我运行以下命令时

select player1_name, count(player1_name) as total from leaderboard_api where year = '2015' and competition_id = '014' group by player1_name order by total desc;

我得到一份球员名单和他们各自的人数。然后我可以分别为 player2_name 和 player3_name 运行它并得到他们的总数。

我遇到的问题是将每个查询中的每个玩家总数添加到另一个查询中以获得总计。我已经分别运行每个并按预期获取值。

我从@sagi 尝试了下面的解决方案,但它没有计算所有 3 个查询的总和,只给了我 1 个作为总数。

SELECT t.player,count(*) FROM (
   SELECT player1 as player FROM `users` UNION ALL
   SELECT player2 FROM `users` UNION ALL
   SELECT player3 FROM `users` UNION ALL
   ....) t
GROUP BY t.player

这是使用查询的前 100 名

select id, player1_name, player2_name, player3_name from leaderboard_api limit 100;

输出:

1   Donald, Luke    Toms, David Bradley, Keegan
2   Stricker, Steve Bradley, Keegan Watson, Bubba
3   Choi, KJ    Westwood, Lee   Bradley, Keegan
4   Scott, Adam Stricker, Steve Immelman, Trevor
5   Stricker, Steve Garcia, Sergio  Haas, Bill
6   Fowler, Rickie  Schwartzel, Charl   Bradley, Keegan
7   Watney, Nick    Stricker, Steve Levin, Spencer
8   Stricker, Steve Johnson, Zach   Bradley, Keegan
9   Donald, Luke    Points, DA  Fowler, Rickie
10  Westwood, Lee   Donald, Luke    Barnes, Ricky
11  Schwartzel, Charl   Choi, KJ    Haas, Bill
12  Woodland, Gary  Choi, KJ    Garcia, Sergio
13  Donald, Luke    Stricker, Steve Molder, Bryce
14  Garcia, Sergio  Kuchar, Matt    Furyk, Jim
15  Noh, Seung-Yul  Kuchar, Matt    Watney, Nick
16  Donald, Luke    Mickelson, Phil Barnes, Ricky
17  Scott, Adam Fowler, Rickie  Noren, Alexander
18  Johnson, Zach   Molinari, Francesco Toms, David
19  Choi, KJ    Westwood, Lee   Poulter, Ian
20  Mcilroy, Rory   Points, DA  Westwood, Lee
21  McIlroy, Rory   Donald, Luke    Na, Kevin
22  Choi, KJ    Scott, Adam Dyson, Simon
23  Fowler, Rickie  Johnson, Zach   Bradley, Keegan
24  Mcilroy, Rory   Scott, Adam Senden, John
25  Mickelson, Phil Kuchar, Matt    Barnes, Ricky
26  Jimenez, Miguel Angel   Mickelson, Phil Westwood, Lee
27  Donald, Luke    Mcilroy, Rory   Palmer, Ryan
28  Mickelson, Phil Choi, KJ    Poulter, Ian
29  Mcilroy, Rory   Mickelson, Phil Points, DA
30  Johnson, Zach   Stricker, Steve Molinari, Francesco
31  Toms, David Love, Davis Mickelson, Phil
32  McIlroy, Rory   Westwood, Lee   Wilson, Mark
33  Mcilroy, Rory   Garcia, Sergio  Immelman, Trevor
34  Garcia, Sergio  Love, Davis Westwood, Lee
35  Donald, Luke    Stricker, Steve Sabbatini, Rory
36  Mcilroy, Rory   Karlsson, Robert    Romero, Andres
37  Choi, KJ    Yang, Y.E   Toms, David
38  Mcilroy, Rory   Watney, Nick    Kirk, Chris
39  Mcilroy, Rory   Kuchar, Matt    Noren, Alexander
40  Scott, Adam Yang, Y.E   Romero, Andres
41  Donald, Luke    Fowler, Rickie  Jimenez, Miguel Angel
42  Donald, Luke    Jimenez, Miguel Angel   Fowler, Rickie
43  Donald, Luke    Love, Davis Choi, KJ
44  Mcilroy, Rory   Westwood, Lee   Barnes, Ricky
45  Donald, Luke    Fowler, Rickie  Molinari, Edoardo
46  Garcia, Sergio  Choi, KJ    Yang, Y.E
47  Choi, KJ    Fowler, Rickie  Dyson, Simon
48  Fowler, Rickie  Molinari, Francesco Johnson, Zach
49  Stricker, Steve Choi, KJ    Casey, Paul
50  McIlroy, Rory   Choi, KJ    Molinari, Francesco
51  Fowler, Rickie  Jimenez, Miguel Angel   Mickelson, Phil
52  Mcilroy, Rory   Garcia, Sergio  Kim, Kyung-Tae
53  Mcilroy, Rory   Garcia, Sergio  Kim, Kyung-Tae
54  Mcilroy, Rory   Mickelson, Phil Barnes, Ricky
55  Mcilroy, Rory   Mickelson, Phil Barnes, Ricky
56  Fowler, Rickie  Mcilroy, Rory   Wilson, Mark
57  Fowler, Rickie  Love, Davis Watson, Bubba
58  Fowler, Rickie  Harrington, Padraig Poulter, Ian
59  McIlroy, Rory   Mickelson, Phil Jimenez, Miguel Angel
60  Mcilroy, Rory   Fowler, Rickie  Jimenez, Miguel Angel
61  Day, Jason  Johnson, Zach   Bradley, Keegan
62  Stricker, Steve Overton, Jeff   Mickelson, Phil
63  Day, Jason  Furyk, Jim  Toms, David
64  Donald, Luke    Westwood, Lee   Gay, Brian
65  Stricker, Steve Day, Jason  Kim, Kyung-Tae
66  Mahan, Hunter   Stricker, Steve Van Pelt, Bo
67  Day, Jason  Scott, Adam Barnes, Ricky
68  Day, Jason  Johnson, Zach   Love, Davis
69  Fowler, Rickie  Jacobson, Fredrik   Bradley, Keegan
70  Karlsson, Robert    Watney, Nick    Quiros, Alvaro
71  Schwartzel, Charl   Johnson, Dustin Love, Davis
72  Mcilroy, Rory   Scott, Adam Slocum, Heath
73  Day, Jason  Johnson, Zach   Dyson, Simon
74  Day, Jason  Johnson, Zach   Dyson, Simon
75  Day, Jason  Mcilroy, Rory   Garrigus, Robert
76  Donald, Luke    Mcilroy, Rory   Byrd, Jonathan
77  Baddeley, Aaron Garcia, Sergio  Toms, David
78  Day, Jason  Kuchar, Matt    Sabbatini, Rory
79  Johnson, Dustin Choi, KJ    Fisher, Ross
80  Simpson, Webb   Stricker, Steve Yang, Y.E
81  Day, Jason  Mickelson, Phil Barnes, Ricky
82  Johnson, Zach   Howell, Charles Snedeker, Brandt
83  Donald, Luke    Mcilroy, Rory   Stallings, Scott
84  Kim, Anthony    Mickelson, Phil Rose, Justin
85  Kaymer, Martin  Marino, Steve   Westwood, Lee
86  Mahan, Hunter   Kaymer, Martin  Poulter, Ian
87  Mcilroy, Rory   Johnson, Dustin Jimenez, Miguel Angel
88  Mcilroy, Rory   Johnson, Dustin Jimenez, Miguel Angel
89  Laird, Martin   Scott, Adam Snedeker, Brandt
90  Johnson, Dustin Johnson, Zach   Manassero, Matteo
91  Day, Jason  Watney, Nick    Tringale, Cameron
92  Garcia, Sergio  Day, Jason  Quiros, Alvaro
93  Day, Jason  Moore, Ryan Toms, David
94  Day, Jason  Mcilroy, Rory   Barnes, Ricky
95  Baddeley, Aaron Mcilroy, Rory   Yang, Y.E
96  Westwood, Lee   Jacobson, Fredrik   Kim, Kyung-Tae
97  Day, Jason  Mcilroy, Rory   Molinari, Edoardo
98  Day, Jason  Garcia, Sergio  Cink, Stewart
99  Bjorn, Thomas   Scott, Adam Woods, Tiger
100 Day, Jason  Johnson, Dustin Levin, Spencer

【问题讨论】:

  • 您能给我们看看您的原始表格,或者至少是其中的一个样本吗?
  • 你应该有一个连接表,每次使用和每个玩家都有一行。 . .可能称为UserPlayers
  • 如果有帮助,添加上面的创建表代码

标签: mysql excel pivot


【解决方案1】:

如果我理解正确,你可以使用UNION ALL

SELECT t.player,count(*) FROM (
   SELECT player1 as player FROM `users` UNION ALL
   SELECT player2 FROM `users` UNION ALL
   SELECT player3 FROM `users` UNION ALL
   ....) t
GROUP BY t.player

编辑:我认为你的名字中有空格,所以它们没有归为一组,试试这个:

SELECT replace(t.player,' ',''),count(*) FROM (
   SELECT player1 as player FROM `users` UNION ALL
   SELECT player2 FROM `users` UNION ALL
   SELECT player3 FROM `users` UNION ALL
   ....) t
GROUP BY replace(t.player,' ','')

您也可以尝试替换此行:

replace(t.player,' ','')

有了这一行:

trim(t.player)

取决于您的数据究竟是什么样的。

【讨论】:

  • 这就是我要找的,但问题是计数全为 1,我正在寻找所有 3 列中每次出现的 t.player 的总数。因此,如果“玩家 A”出现在 player1 3 次、player2 5 次和 player3 4 次,那么上面的结果集是否应该将“player A”计为 12 是否有意义?
  • 我给你的查询有什么问题?这就是它的作用。 @艾伦
  • 它只是使用计数(*)将所有行总计为 1,我正在寻找 t.player 每次出现的实际计数,所以如果 playerA 在 player1 中出现 3 次,在 player1 中出现 4 次player2 和 player3 中的 5 次,那么我应该得到 t.player = playerA 和 total = 12。这是否清楚?
  • 再一次,我明白你想要什么,这就是它应该做的。我怀疑您的数据或其呈现方式不正确。请更新您的问题并添加您的数据示例,然后您希望从中获得什么@alan
  • 我已经用预期的结果和实际的查询更新了我的问题,这给了我我期望从数据库得到的结果。我只是不确定为什么它只计数到 1,但它给了我返回的正确名称列表。
【解决方案2】:

从上面的@sagi 开始解决方案后,我最终解决了这个问题,如果那是正确的语言,子表中会丢失计数。

这是我为可能需要它的人提供的解决方案...

select t.player, sum(count) as total from (
select player1_name as player, count(player1_name) as count from leaderboard_api where year = '2015' and competition_id = '033' group by player1_name
UNION
select player2_name, count(player2_name) as count from leaderboard_api where year = '2015' and competition_id = '033' group by player2_name
UNION
select player3_name, count(player3_name) as count from leaderboard_api where year = '2015' and competition_id = '033' group by player3_name)
t group by t.player order by total desc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    相关资源
    最近更新 更多