MySQL匹配行值集

时间:2015-06-26 04:57:37

标签: mysql matching

我对mysql和php比较新。我开发了一个曲棍球stat db。到目前为止,我一直在做非常基本的查询和报告统计数据。 我现在想做一些更高级的查询。
我有一张桌子记录哪些球员在冰上(显示为" fk_pp1_id" - " fk_pp5_id")进球得分时。这是表格:

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

我想做几个查询:

  1. 显示最常见的五名球员中哪一位在冰上 当进球得分时。
  2. 选择说出2名球员,并在进球时最常与他们一起出示哪些球员。
  3. 我能够编写一个部分完成上面的查询#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

    所以为了解决这个问题,我觉得我有几个选择:

    1. 确保数据按数字顺序输入表中

    2. 重新编写查询,以便表格中数据的顺序无关紧要

    3. 首先将结果查询作为另一个查询的子查询 按数字顺序对列(从左到右)进行排序。

    4. 更改架构以更好地记录/存储数据

    5. 1,我可以做,但更愿意让查询变得万无一失 我更喜欢2或3,但不知道如何做 4,我不知道该怎么做而且最不可取,因为我已经有一些复杂的查询需要完全重写。

      我是以错误的方式解决这个问题还是有解决办法? 谢谢你的帮助

      更新 - 好的(希望)能更好地规范化表格中的数据。谢谢@strawberry。现在我的表有一个goal_id(外键)的列和一个在目标得分时在冰上的player_id(另一个外键)的列。

      这是新的小提琴: http://sqlfiddle.com/#!9/39e5a

      当进球得分时,我可以很容易地得到一名最出现在冰面上的球员,但是我无法理解如何找到一组冰球队员的出现。例如,一组5名球员一起出现多少次。然后从那里开始,一组2名球员和其他3名球员一起出现在冰上。

      任何其他线索???

1 个答案:

答案 0 :(得分:0)

我发现了一个类似的问题here,并基于此我提出了这个解决方案。

对于问题的第一部分,当目标得分时,选择同一个五名玩家在冰上的时间,您的查询可能如下所示:

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;

对于问题的第二部分,你想要选择两名球员并找到另外三名球员,当进球得分时,你应该扩展之前的查询whit WERE条款

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;

您可以在SQL Fiddle ...

中查看它的工作原理

注意:我在表1中添加了一些数据(不要与更多日期计算混淆)。

GL!