COID与案例陈述无法正常工作

时间:2018-06-16 08:59:13

标签: mysql sql

假设我的查询中有以下输出:

{
    "player_first_name": "Albano",
    "player_last_name": "Aleksi",
    "yellow_cards": "14",
    "orange_cards": "0",
    "red_cards": "1",
    "points": "15",
    "player_id": "286635"
}

你可以看到玩家有14张黄牌,1张红牌和0张橙卡。

我想计算"点"这个玩家通过以下方式计算每张卡的收入:

  • 黄牌:1分
  • 橙卡:2点
  • 红牌:3分

所以最终的结果应该是:17

我试图用以下方式计算得分总数:

$sql = $this->db->prepare("SELECT
    p.first_name AS player_first_name,
    p.last_name AS player_last_name,
    COUNT(CASE
      WHEN c.card_id = 1 THEN 1
      END) AS yellow_cards,
    COUNT(CASE WHEN c.card_id = 2 THEN 1 END) AS orange_cards,
    COUNT(CASE
      WHEN c.card_id = 3 THEN 1
      END) AS red_cards,
    COUNT(CASE
      WHEN c.card_id = 1 THEN 1
      WHEN c.card_id = 2 THEN 2
      WHEN c.card_id = 3 THEN 3
      END) AS points,
    p.id AS player_id
    FROM `match` m
    INNER JOIN player_cards c ON c.match_id = m.id
    INNER JOIN player p ON c.player_id = p.id
    WHERE m.round_id = :round_id
    GROUP BY p.id
    ORDER BY points DESC, player_last_name ASC");

你可以看到我有以下声明:

 COUNT(CASE
      WHEN c.card_id = 1 THEN 1
      WHEN c.card_id = 2 THEN 2
      WHEN c.card_id = 3 THEN 3
      END) AS points,

卡片ID对应颜色的ID,所以:

  • 1:黄牌
  • 2:橙卡
  • 3:红牌

为什么toal不正确?

更新

预期产出:

{
    "player_first_name": "Albano",
    "player_last_name": "Aleksi",
    "yellow_cards": "14",
    "orange_cards": "0",
    "red_cards": "1",
    "points": "17",
    "player_id": "286635"
}

你可以看到points17因为我们有14张黄牌(每张黄牌值1分),我们有1张红牌,每张红牌值3分,所以:14 + 3 = 17.但我得到15

6 个答案:

答案 0 :(得分:3)

由于您只想将卡的数值相加以获得总数,因此只需使用SUM(card_id)代替COUNT

SELECT
    p.first_name AS player_first_name,
    p.last_name AS player_last_name,
    COUNT(CASE WHEN c.card_id = 1 THEN 1 END) AS yellow_cards,
    COUNT(CASE WHEN c.card_id = 2 THEN 1 END) AS orange_cards,
    COUNT(CASE WHEN c.card_id = 3 THEN 1 END) AS red_cards,
    SUM(c.card_id) AS points,
    p.id AS player_id
FROM match m
INNER JOIN player_cards c
    ON c.match_id = m.id
INNER JOIN player p
    ON c.player_id = p.id
WHERE
    m.round_id = :round_id
GROUP BY
    p.id
ORDER BY
    points DESC, player_last_name;

您的PHP代码应如下所示:

$stmt = $connection->prepare();
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    $red = $row["red_cards"];
    $yel = $row["yellow_cards"];
    $orange = $row["orange_cards"];
    $points = $row["points"];
}

答案 1 :(得分:1)

如果您尝试通过查询数据库中的卡来计算点数,将其保存在变量中,然后在SQL中不使用任何内联CASE语句对它们进行计数,该怎么办?做一个简单的查询,你可以获得每个玩家的红色,橙色和黄色卡片,然后按照例子计算它们。

// The query to get the cards, name etc.
$sql = "SELECT
p.first_name AS player_first_name,
p.last_name AS player_last_name,
c.card_id = 1 THEN 1 AS yellow_cards
c.card_id = 2 THEN 2 AS orange_cards
c.card_id = 3 THEN 3 AS red_cards
p.id AS player_id
FROM `match` m
INNER JOIN player_cards c ON c.match_id = m.id
INNER JOIN player p ON c.player_id = p.id
WHERE m.round_id = round_id
GROUP BY p.id
ORDER BY points DESC, player_last_name ASC";

// Prepared statement to get the cards as variables and then count the points
$stmt = $connection->prepare();
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_assoc()){
    $red = $row["red_cards"];
    $yel = $row["yellow_cards"];
    $orange = $row["orange_cards"];
    $points = $red * 3 + $orange * 2 + $yel;
}

请注意,我在示例中使用了预处理语句,$connection变量涵盖了与服务器的mySQL连接。

答案 2 :(得分:1)

替换

COUNT(CASE
      WHEN c.card_id = 1 THEN 1
      WHEN c.card_id = 2 THEN 2
      WHEN c.card_id = 3 THEN 3
      END) AS points,

SUM(CASE
    WHEN c.card_id = 1 THEN 1
    WHEN c.card_id = 2 THEN 2
    WHEN c.card_id = 3 THEN 3
    END) AS points,

因为有了计数,你只需要数,而你真的想要总和。如果您计算数字1,1,1,1,1,1,1,1,1,1,1,1,1,3,3,如果您,则得到15加起来你得到十七岁。

但是,card_id显然有一张卡片表。这个card表自然应该包含卡的值。所以加入卡表并使用

SUM(card.value)

而不是上述。

答案 3 :(得分:0)

只需将count替换为sum,然后重试。

答案 4 :(得分:0)

正如其他答案所述,count()计算 - NULL结果的数量。因此,0与任何其他值一样非NULL

但是,MySQL还提供了一个不使用CASE的便捷快捷方式。布尔表达式在数字上下文中被视为数字,“1”表示true,“0”表示false。所以:

SELECT p.first_name AS player_first_name, p.last_name AS player_last_name,
       SUM( c.card_id = 1 ) AS yellow_cards,
       SUM( c.card_id = 2 ) AS orange_cards,
       SUM( c.card_id = 3 ) AS red_cards,
       SUM( CASE WHEN c.card_id IN (1, 2, 3) THEN c.card_id ELSE 0 END) AS points,
       p.id AS player_id
FROM `match` m INNER JOIN
     player_cards c
     ON c.match_id = m.id INNER JOIN
     player p ON c.player_id = p.id
WHERE m.round_id = :round_id
GROUP BY p.id
ORDER BY points DESC, player_last_name ASC;

如果唯一允许的card_id是0,1,2和3,那么点数计算可以简化为:

       SUM( c.card_id ) AS points,

答案 5 :(得分:0)

最简单的代码是:

SUM(c.card_id) AS points,

如果您不想依赖card_id具有certian值,那么这是下一个最简单的:

SUM((c.card_id = 1) + 2 * (c.card_id = 2) + 3 * (c.card_id = 3)) 

这是有效的,因为在MySQL true1false0