【问题标题】:How to count the same field for different times?如何计算不同时间的相同字段?
【发布时间】:2018-06-13 17:15:26
【问题描述】:

我需要从我的数据库中提取特定球员的所有进球数。我有这个桌子设计:

比赛

id | home | away | result | round_id

播放器

id | first_name | last_name

目标

match_id | player_marker_id | type

GOAL_TYPE

id | description

基本上goal 表包含match 中的所有进球,该表将match_id 字段绑定为FKmatch.id。字段player_marker_idplayer.idFKgoal_type 包含一个目标可以假设的所有类型,一个目标有4 种状态:

1: first_goal
2: goal
3: pg
4: og

我需要做的是返回得分最高的玩家,计算有多少first_goal, goal, pg。我不需要返回og,因为它对应于auto goal.

我现在做了什么:

$sql = $this->db->prepare("SELECT
p.first_name AS player_first_name,
p.last_name AS player_last_name,
COUNT(*) AS goal_scored,
p.id AS player_id
FROM `match` m
INNER JOIN goal g ON g.match_id = m.id
INNER JOIN player p ON g.player_marker_id = p.id
WHERE m.round_id = :round_id AND g.type != 4
GROUP BY p.id
ORDER BY goal_scored DESC, player_last_name DESC");

这个查询正在运行,但没有返回预期的结果,事实上我得到了:

{
    "player_first_name": "Ali",
    "player_last_name": "Sowe",
    "goal_scored": "21",
    "player_id": "246638"
},
{
    "player_first_name": "Sindrit",
    "player_last_name": "Guri",
    "goal_scored": "20",
    "player_id": "211786"
},

我会返回这个输出:

 {
    "player_first_name": "Ali",
    "player_last_name": "Sowe",
    "goal_scored": "21",
    "player_id": "246638", 
    "first_goal": "19",
    "goal": "1",
    "pg": "1"
}

我也尝试过这样做:

$sql = $this->db->prepare("SELECT
p.first_name AS player_first_name,
p.last_name AS player_last_name,
COUNT(*) AS goal_scored,
CASE g.type
  WHEN 1 THEN 'first_goal'
  WHEN 2 THEN 'goal'
  WHEN 3 THEN 'pg'
  WHEN 4 THEN 'og'
END AS goal_type,
p.id AS player_id
FROM `match` m
INNER JOIN goal g ON g.match_id = m.id
INNER JOIN player p ON g.player_marker_id = p.id
WHERE m.round_id = :round_id AND g.type != 4
GROUP BY p.id
ORDER BY goal_scored DESC, player_last_name DESC");

但这会返回:

SQLSTATE[42000]:语法错误或访问冲突:1055 SELECT 列表的表达式 #4 不在 GROUP BY 子句中,并且包含在功能上不依赖于 GROUP BY 子句中的列的非聚合列“swp.g.type”;这与 sql_mode=only_full_group_by 不兼容

我猜这不是正确的方法。

round_id 是比赛所在的联赛。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    您可以通过将 case 语句移动到 count 聚合函数内部来仅计算给定目标类型的记录。试试这个:

    SELECT
    p.first_name AS player_first_name,
    p.last_name AS player_last_name,
    COUNT(*) AS goal_scored,
    COUNT(case when g.type = 1 then 1 else null end) as first_goal,
    COUNT(case when g.type = 2 then 1 else null end) as goal,
    COUNT(case when g.type = 3 then 1 else null end) as pg,
    p.id AS player_id
    FROM `match` m
    INNER JOIN goal g ON g.match_id = m.id
    INNER JOIN player p ON g.player_marker_id = p.id
    WHERE m.round_id = :round_id AND g.type != 4
    GROUP BY p.id
    ORDER BY goal_scored DESC, player_last_name DESC 
    

    【讨论】:

      【解决方案2】:

      好吧,如果您找不到更好的解决方案,您始终可以使用 TOP(在 SQL Server 中)或 LIMIT(在 MySQL 中)来指定返回的结果数。我假设您的第一个解决方案中返回的第一条记录是正确的。这是如何使用它们的链接https://www.w3schools.com/sql/sql_top.asp

      【讨论】:

        猜你喜欢
        • 2020-04-13
        • 1970-01-01
        • 1970-01-01
        • 2017-10-12
        • 2020-05-20
        • 1970-01-01
        • 1970-01-01
        • 2012-07-09
        • 2019-10-24
        相关资源
        最近更新 更多