[英]How to sum a field of a child table by a parent table field when a second child table has records?
給定以下三個示例表:
錦標賽_oc
ID_ |
---|
1 |
2 |
match_oc:
ID_ | 錦標賽_oc_id |
---|---|
1 | 1 |
2 | 1 |
stat_oc
ID_ | 錦標賽_oc_id | 價值_ |
---|---|---|
1 | 1 | 1 |
2 | 1 | 1 |
3 | 2 | 1 |
如果給定的tournament_oc.id_
oc.id_ 有一個或多個match_oc
記錄,我想將stat_oc.value_
與tournament_oc.id_
oc.id_ 相加。 在這種情況下,所需的輸出應該是:
錦標賽_oc_id | sum_value |
---|---|
1 | 2 |
我試過了:
SELECT
t.id_ AS tournament_oc_id, sum(s.value_) AS sum_value
FROM
tournament_oc AS t
JOIN
match_oc AS m ON m.tournament_oc_id = t.id_
JOIN
stat_oc as s on s.tournament_oc_id = t.id_
GROUP BY t.id_
但是,這會返回:
錦標賽_oc_id | sum_value |
---|---|
1 | 4 |
大概是因為有兩條match_oc
記錄,其中tournament_oc.id_
oc.id_ == 1。
我將如何達到預期的結果?
用於復制表的 SQL:
CREATE DATABASE IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `test`;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `match_oc`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `match_oc` (
`id_` int NOT NULL AUTO_INCREMENT,
`tournament_oc_id` int NOT NULL,
PRIMARY KEY (`id_`),
KEY `fk__match_oc__tournament_oc_id_idx` (`tournament_oc_id`),
CONSTRAINT `fk__match_oc__tournament_oc_id` FOREIGN KEY (`tournament_oc_id`) REFERENCES `tournament_oc` (`id_`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
LOCK TABLES `match_oc` WRITE;
/*!40000 ALTER TABLE `match_oc` DISABLE KEYS */;
INSERT INTO `match_oc` VALUES (1,1),(2,1);
/*!40000 ALTER TABLE `match_oc` ENABLE KEYS */;
UNLOCK TABLES;
DROP TABLE IF EXISTS `stat_oc`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `stat_oc` (
`id_` int NOT NULL AUTO_INCREMENT,
`tournament_oc_id` int NOT NULL,
`value_` tinyint DEFAULT NULL,
PRIMARY KEY (`id_`),
KEY `fk__stat_oc__tournament_oc_id_idx` (`tournament_oc_id`),
CONSTRAINT `fk__stat_oc__tournament_oc_id` FOREIGN KEY (`tournament_oc_id`) REFERENCES `tournament_oc` (`id_`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
LOCK TABLES `stat_oc` WRITE;
/*!40000 ALTER TABLE `stat_oc` DISABLE KEYS */;
INSERT INTO `stat_oc` VALUES (1,1,1),(2,1,1),(3,2,1);
/*!40000 ALTER TABLE `stat_oc` ENABLE KEYS */;
UNLOCK TABLES;
DROP TABLE IF EXISTS `tournament_oc`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `tournament_oc` (
`id_` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id_`)
) ENGINE=InnoDB AUTO_INCREMENT=26193 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
LOCK TABLES `tournament_oc` WRITE;
/*!40000 ALTER TABLE `tournament_oc` DISABLE KEYS */;
INSERT INTO `tournament_oc` VALUES (1),(2);
/*!40000 ALTER TABLE `tournament_oc` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
您不能在JOIN
操作的同一級別上進行聚合,只要在聚合之前執行此操作即可,因此,如果錦標賽在多場比賽中進行了比賽,您將獲得每場比賽的重復總和(在你的情況,2匹配2 = 4)。
為了規避這個問題,你可以先過濾掉沒有匹配的錦標賽(在WHERE
子句中),然后總結你的錦標賽。
SELECT tournament_oc_id,
SUM(value_) AS sum_value
FROM stat_oc
WHERE tournament_oc_id IN (SELECT tournament_oc_id FROM match_oc)
GROUP BY tournament_oc_id
只要假設如果錦標賽不存在,它也不應該出現在“ match_oc ”表中,就沒有必要使用“ tournament_oc ”表。
在此處查看演示。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.