MySQL 匹配行值集
MySQL matching row values sets
我对 mysql 和 php 比较陌生。我开发了一个曲棍球统计数据库。到目前为止,我一直在做非常基本的查询和统计报告。
我现在想做一些更高级的查询。
我有一个 table 记录进球时哪些球员在冰上(显示为 "fk_pp1_id" - "fk_pp5_id")。这是 table:
pt_id | fk_gf_id | fk_pp1_id | fk_pp2_id | fk_pp3_id | fk_pp4_id | fk_pp5_id
1 | 1 | 19 | 20 | 68 | 90 | 97
2 | 2 | 1 | 19 | 20 | 56 | 91
3 | 3 | 1 | 56 | 88 | 91 | 93
4 | 4 | 1 | 19 | 64 | 88 | NULL
5 | 5 | 19 | 62 | 68 | 88 | 97
6 | 6 | 55 | 19 | 20 | 45 | 62
7 | 7 | 1 | 19 | 20 | 56 | 61
8 | 8 | 65 | 68 | 90 | 93 | 97
9 | 9 | 19 | 20 | 45 | 55 | 62
10 | 10 | 1 | 19 | 20 | 56 | 61
11 | 11 | 1 | 19 | 20 | 56 | 61
12 | 12 | 19 | 20 | 68 | 90 | 97
13 | 13 | 19 | 20 | 68 | 90 | 97
14 | 14 | 19 | 20 | 55 | 62 | 91
15 | 15 | 1 | 56 | 61 | 64 | 88
16 | 16 | 1 | 56 | 61 | 64 | 88
17 | 17 | 1 | 19 | 20 | 56 | 61
18 | 18 | 1 | 19 | 20 | 56 | 61
19 | 19 | 1 | 65 | 68 | 93 | 97
我想做几个查询:
- 显示五名球员中哪一位最常一起在冰上
进球时。
- Select 说 2 名球员,并显示进球时哪些其他球员最常与他们一起在冰上。
我能够编写一个部分完成上述查询 #1 的查询。
SELECT
fk_pp1_id,
fk_pp2_id,
fk_pp3_id,
fk_pp4_id,
fk_pp5_id,
count(*)
FROM TABLE1
group by
fk_pp1_id,
fk_pp2_id,
fk_pp3_id,
fk_pp4_id,
fk_pp5_id
结果如下:
fk_pp1_id fk_pp2_id fk_pp3_id fk_pp4_id fk_pp5_id count(*)
1 19 20 56 61 4
1 19 20 56 91 1
1 19 64 88 (null) 1
1 56 61 64 88 2
1 56 88 91 93 1
1 65 68 93 97 1
19 1 20 56 61 1
19 20 45 55 62 1
19 20 55 62 91 1
19 20 68 90 97 3
19 62 68 88 97 1
55 19 20 45 62 1
65 68 90 93 97 1 4
看到这个sqlfiddle:
http://sqlfiddle.com/#!9/e3f5f/1
一开始这似乎可行,但我意识到这个查询,正如所写的那样,对列出球员的顺序很敏感。也就是说一行:
1, 19, 20, 68, 90
不匹配
19、1、20、68、90
所以要解决这个问题,我觉得我有几个选择:
确保数据按数字顺序输入table
重新编写查询,使 table 中的数据顺序无关紧要
将生成的查询作为第一个查询的另一个查询的子查询
按数字顺序(从左到右)对列进行排序。
以更好的方式将架构更改为record/store数据
1,我可以,但希望查询是万无一失的。
2 或 3 我更喜欢,但都不知道该怎么做。
4,我不知道该怎么做,这是最不可取的,因为我已经有一些针对此的复杂查询 table 需要完全重写。
我是不是用错了方法或者有解决办法吗??
感谢您的帮助
更新 -
好的,我(希望)更好地规范化 table 中的数据。谢谢@草莓。现在我的 table 有一个 goal_id (外键)列和一个 player_id (另一个外键)列,它们在进球时在冰上。
这是新的 fiddle:
http://sqlfiddle.com/#!9/39e5a
我可以很容易地找到进球时上场次数最多的球员,但我不知道如何找到一组球员一起上场的次数。比如5个人一组一起上冰多少次。然后从那里开始,一组 2 名球员与其他 3 名球员一起在冰上的频率。
还有其他线索吗???
I find a similar problem here and based on that i come up with this solution.
For the first part of your problem to select how many time same five player were on the ice when the goal is scored your query could look like this:
SELECT GROUP_CONCAT(t1.fk_gf_id) AS MinOfGoal,
t1.players AS playersNumber,
COUNT(t1.fk_gf_id) AS numOfTimes
FROM (SELECT fk_gf_id, GROUP_CONCAT(fk_plyr_id ORDER BY fk_plyr_id) AS players
FROM Table1
GROUP BY fk_gf_id) AS t1
GROUP BY t1.players
ORDER BY numOfTimes DESC;
And for your second part of the question where you want to select two players and find three more player which were on the ice when goal were scored you should extend previous query whit WERE clause like this
SELECT GROUP_CONCAT(t1.fk_gf_id) AS MinOfGoal,
t1.players AS playersNumber,
COUNT(t1.fk_gf_id) AS numOfTimes
FROM (SELECT fk_gf_id, GROUP_CONCAT(fk_plyr_id ORDER BY fk_plyr_id) AS players
FROM Table1
WHERE fk_gf_id IN (SELECT fk_gf_id
FROM Table1
WHERE fk_plyr_id = 19)
AND fk_gf_id IN (SELECT fk_gf_id
FROM Table1
WHERE fk_plyr_id = 56)
GROUP BY fk_gf_id) AS t1
GROUP BY t1.players
ORDER BY numOfTimes DESC;
You can see how it's work here in SQL Fiddle...
Note: I added some data in Table1 (don't be confused with more date counted).
GL!
我对 mysql 和 php 比较陌生。我开发了一个曲棍球统计数据库。到目前为止,我一直在做非常基本的查询和统计报告。
我现在想做一些更高级的查询。
我有一个 table 记录进球时哪些球员在冰上(显示为 "fk_pp1_id" - "fk_pp5_id")。这是 table:
pt_id | fk_gf_id | fk_pp1_id | fk_pp2_id | fk_pp3_id | fk_pp4_id | fk_pp5_id 1 | 1 | 19 | 20 | 68 | 90 | 97 2 | 2 | 1 | 19 | 20 | 56 | 91 3 | 3 | 1 | 56 | 88 | 91 | 93 4 | 4 | 1 | 19 | 64 | 88 | NULL 5 | 5 | 19 | 62 | 68 | 88 | 97 6 | 6 | 55 | 19 | 20 | 45 | 62 7 | 7 | 1 | 19 | 20 | 56 | 61 8 | 8 | 65 | 68 | 90 | 93 | 97 9 | 9 | 19 | 20 | 45 | 55 | 62 10 | 10 | 1 | 19 | 20 | 56 | 61 11 | 11 | 1 | 19 | 20 | 56 | 61 12 | 12 | 19 | 20 | 68 | 90 | 97 13 | 13 | 19 | 20 | 68 | 90 | 97 14 | 14 | 19 | 20 | 55 | 62 | 91 15 | 15 | 1 | 56 | 61 | 64 | 88 16 | 16 | 1 | 56 | 61 | 64 | 88 17 | 17 | 1 | 19 | 20 | 56 | 61 18 | 18 | 1 | 19 | 20 | 56 | 61 19 | 19 | 1 | 65 | 68 | 93 | 97
我想做几个查询:
- 显示五名球员中哪一位最常一起在冰上 进球时。
- Select 说 2 名球员,并显示进球时哪些其他球员最常与他们一起在冰上。
我能够编写一个部分完成上述查询 #1 的查询。
SELECT fk_pp1_id, fk_pp2_id, fk_pp3_id, fk_pp4_id, fk_pp5_id, count(*) FROM TABLE1 group by fk_pp1_id, fk_pp2_id, fk_pp3_id, fk_pp4_id, fk_pp5_id
结果如下:
fk_pp1_id fk_pp2_id fk_pp3_id fk_pp4_id fk_pp5_id count(*) 1 19 20 56 61 4 1 19 20 56 91 1 1 19 64 88 (null) 1 1 56 61 64 88 2 1 56 88 91 93 1 1 65 68 93 97 1 19 1 20 56 61 1 19 20 45 55 62 1 19 20 55 62 91 1 19 20 68 90 97 3 19 62 68 88 97 1 55 19 20 45 62 1 65 68 90 93 97 1 4
看到这个sqlfiddle:
http://sqlfiddle.com/#!9/e3f5f/1
一开始这似乎可行,但我意识到这个查询,正如所写的那样,对列出球员的顺序很敏感。也就是说一行: 1, 19, 20, 68, 90 不匹配 19、1、20、68、90
所以要解决这个问题,我觉得我有几个选择:
确保数据按数字顺序输入table
重新编写查询,使 table 中的数据顺序无关紧要
将生成的查询作为第一个查询的另一个查询的子查询 按数字顺序(从左到右)对列进行排序。
以更好的方式将架构更改为record/store数据
1,我可以,但希望查询是万无一失的。
2 或 3 我更喜欢,但都不知道该怎么做。
4,我不知道该怎么做,这是最不可取的,因为我已经有一些针对此的复杂查询 table 需要完全重写。
我是不是用错了方法或者有解决办法吗??
感谢您的帮助
更新 - 好的,我(希望)更好地规范化 table 中的数据。谢谢@草莓。现在我的 table 有一个 goal_id (外键)列和一个 player_id (另一个外键)列,它们在进球时在冰上。
这是新的 fiddle: http://sqlfiddle.com/#!9/39e5a
我可以很容易地找到进球时上场次数最多的球员,但我不知道如何找到一组球员一起上场的次数。比如5个人一组一起上冰多少次。然后从那里开始,一组 2 名球员与其他 3 名球员一起在冰上的频率。
还有其他线索吗???
I find a similar problem here and based on that i come up with this solution.
For the first part of your problem to select how many time same five player were on the ice when the goal is scored your query could look like this:
SELECT GROUP_CONCAT(t1.fk_gf_id) AS MinOfGoal,
t1.players AS playersNumber,
COUNT(t1.fk_gf_id) AS numOfTimes
FROM (SELECT fk_gf_id, GROUP_CONCAT(fk_plyr_id ORDER BY fk_plyr_id) AS players
FROM Table1
GROUP BY fk_gf_id) AS t1
GROUP BY t1.players
ORDER BY numOfTimes DESC;
And for your second part of the question where you want to select two players and find three more player which were on the ice when goal were scored you should extend previous query whit WERE clause like this
SELECT GROUP_CONCAT(t1.fk_gf_id) AS MinOfGoal,
t1.players AS playersNumber,
COUNT(t1.fk_gf_id) AS numOfTimes
FROM (SELECT fk_gf_id, GROUP_CONCAT(fk_plyr_id ORDER BY fk_plyr_id) AS players
FROM Table1
WHERE fk_gf_id IN (SELECT fk_gf_id
FROM Table1
WHERE fk_plyr_id = 19)
AND fk_gf_id IN (SELECT fk_gf_id
FROM Table1
WHERE fk_plyr_id = 56)
GROUP BY fk_gf_id) AS t1
GROUP BY t1.players
ORDER BY numOfTimes DESC;
You can see how it's work here in SQL Fiddle...
Note: I added some data in Table1 (don't be confused with more date counted).
GL!