【发布时间】:2019-03-16 22:24:03
【问题描述】:
我有 50 个数据库,用于 50 个中心,用于记录所执行的外科手术。我可以很容易地计算每个中心的这些程序的数量:
SELECT
ub.Krankenhaus AS "Zentrum",
"01" AS "ZentrumID",
SUM(op.OP1OPVerfahren = "0") AS "Keine Operation durchgeführt",
SUM(op.OP1OPVerfahren = "1") AS "Bioenterics Intragastric Ballon (BIB)",
SUM(op.OP1OPVerfahren = "2") AS "Gastric Banding",
SUM(op.OP1OPVerfahren = "3") AS "Roux-en-Y Gastric Bypass",
SUM(op.OP1OPVerfahren = "4") AS "Roux-en-Y Gastric Bypass banded",
SUM(op.OP1OPVerfahren = "5") AS "Scopinaro",
SUM(op.OP1OPVerfahren = "6") AS "Duodenal Switch (DS)",
SUM(op.OP1OPVerfahren = "7") AS "Sleeve Resection",
SUM(op.OP1OPVerfahren = "8") AS "Gastric Pacemaker",
SUM(op.OP1OPVerfahren = "9") AS "Billroth II",
SUM(op.OP1OPVerfahren = "10") AS "Gastroplasty",
SUM(op.OP1OPVerfahren = "11") AS "Fobi / Capella Bypass",
SUM(op.OP1OPVerfahren = "12") AS "Larrad",
SUM(op.OP1OPVerfahren = "13") AS "Santoro",
SUM(op.OP1OPVerfahren = "14") AS "DJB",
SUM(op.OP1OPVerfahren = "15") AS "TOGA",
SUM(op.OP1OPVerfahren = "16") AS "Endobarrier",
SUM(op.OP1OPVerfahren = "17") AS "Gastric Plication",
SUM(op.OP1OPVerfahren = "18") AS "Stomaphyx",
SUM(op.OP1OPVerfahren = "19") AS "Omega Loop Bypass",
SUM(op.OP1OPVerfahren = "20") AS "Omega Loop Bypass banded",
SUM(op.OP1OPVerfahren = "21") AS "Long Limb Bypass",
SUM(op.OP1OPVerfahren = "22") AS "Distal Very Long Gastric Bypass (Thurnheer)",
SUM(op.OP1OPVerfahren = "23") AS "Endoscopic Sclerosation",
SUM(op.OP1OPVerfahren = "24") AS "Swedish Adjustable Gastric Bypass (SAGB)",
SUM(op.OP1OPVerfahren = "25") AS "Vertical Banded Gastroplasty (VBG)",
SUM(op.OP1OPVerfahren = "26") AS "Plastic Abdominal Wall Reconstruction (PAWR)",
SUM(op.OP1OPVerfahren = "27") AS "Inner Hernia Repair",
SUM(op.OP1OPVerfahren = "28") AS "Single Anastomosis Duodeno-Ileal Bypass with Sleeve Gastrectomy (SADI-S)",
SUM(op.OP1OPVerfahren = "99") AS "Anderes OP-Verfahren",
SUM(op.OP1OPVerfahren LIKE "%") AS "Summe"
FROM ods01.dat_patient p
LEFT OUTER JOIN ods01.dat_optherapie op ON op.patID = p.ID
LEFT OUTER JOIN ods01.users_benutzer ub ON ub.ID = p.UserID
WHERE 1 = 1
AND op.OP1Datum BETWEEN "2019-01-01" AND "2019-12-31"
AND p.Testzwecke = 0
AND ub.ID = p.UserID
AND NOT EXISTS (SELECT 1
FROM ods01.dat_optherapie op2
WHERE op2.PatID = p.ID AND op2.revision > op.revision
)
结果是一个很好的列表,我可以使用 PHP 进行布局,以便我在左列中接收所有手术,在右列中接收相应的绝对数字:
使用
AND NOT EXIST blah
SQL 查询末尾的语句我只允许最新的记录集修订。
使用
UNION ALL
我可以将所有 50 个中心的结果一个接一个地合并到这样的表格中。显示它们需要更长的滚动时间,但它可以工作。
但是:
如何仅创建一个结果表,其中包含来自所有 50 个中心的所有手术的 SUM(SUM 上的 SUM)?
为了让事情更具体,这里是 MCVE:
CREATE TABLE `dat_optherapie` (
`ID` INT(10) NOT NULL AUTO_INCREMENT,
`patID` INT(10) NOT NULL,
`OP1Datum` DATE NOT NULL,
`OP1OPVerfahren` TINYINT(4) NOT NULL,
`revision` INT(11) NOT NULL,
PRIMARY KEY (`ID`),
INDEX `ix_dat_optherapie_patid` (`patID`, `ID`, `OP1Datum`, `OP1OPVerfahren`, `revision`)
)
COLLATE='latin1_german1_ci'
ENGINE=MyISAM
AUTO_INCREMENT=7798;
这里有一些插入:
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3307, 3005, '2017-06-22', 1, 2);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3308, 3005, '2017-06-22', 1, 3);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3960, 3005, '2017-06-22', 1, 4);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3977, 3005, '2017-06-22', 1, 5);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4246, 3005, '2017-06-22', 1, 6);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5571, 3005, '2017-06-22', 1, 7);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3578, 3067, '2017-09-21', 7, 1);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3579, 3067, '2017-09-21', 7, 2);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3621, 3067, '2017-09-21', 7, 3);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3661, 2905, '2017-03-15', 7, 2);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3846, 2905, '2017-03-15', 7, 3);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4165, 3067, '2017-09-21', 7, 4);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4378, 2905, '2017-03-15', 7, 4);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4704, 3251, '2018-03-27', 99, 1);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4705, 3251, '2018-03-27', 99, 2);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4706, 3251, '2018-03-27', 99, 3);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4707, 3251, '2018-03-27', 99, 4);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4708, 3251, '2018-03-27', 99, 5);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4735, 3251, '2018-03-27', 99, 6);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (4845, 2905, '2017-03-15', 7, 5);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5142, 3251, '2018-03-27', 99, 7);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5415, 3067, '2017-09-21', 7, 5);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5416, 3067, '2017-09-21', 7, 6);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5588, 3251, '2018-03-27', 99, 8);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5589, 3251, '2018-03-27', 99, 9);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5590, 3251, '2018-03-27', 99, 10);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5591, 3251, '2018-03-27', 99, 11);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (5891, 2905, '2017-03-15', 7, 6);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (6007, 3362, '2018-09-18', 19, 0);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (6008, 3362, '2018-09-18', 19, 1);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (6045, 3362, '2018-09-18', 19, 2);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (6061, 3251, '2018-03-27', 99, 12);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (6097, 3251, '2018-03-27', 99, 13);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (6554, 3251, '2018-03-27', 99, 14);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (6555, 3251, '2018-03-27', 99, 15);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3042, 3010, '2017-07-10', 0, 1);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3043, 3010, '2017-07-10', 19, 2);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3047, 3010, '2017-07-10', 19, 3);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3048, 3010, '2017-07-10', 19, 4);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3049, 3010, '2017-07-10', 19, 5);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3066, 3010, '2017-07-10', 19, 6);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3067, 3010, '2017-07-10', 19, 7);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3073, 2968, '2017-05-08', 19, 2);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3074, 2968, '2017-05-08', 19, 3);
INSERT INTO `dat_optherapie` (`ID`, `patID`, `OP1Datum`, `OP1OPVerfahren`, `revision`) VALUES (3075, 2968, '2017-05-08', 19, 4);
表dat_patient 仅用于整数字段Testzwecke,对于非测试患者,该字段必须设置为0。表users_benutzer这里可以完全省略(我把它留在上面的原始代码中),它没有任何意义。表dat_optherapie 中的字段OP1OPVerfahren 只是相应手术过程的整数(也可以是字符串)值。
预期的结果是我已经在上传的屏幕截图中概述的。
这里是上面 SQL 查询的简化示例:
SELECT
SUM(op.OP1OPVerfahren = "0") AS "Keine Operation durchgeführt",
SUM(op.OP1OPVerfahren = "1") AS "Bioenterics Intragastric Ballon (BIB)",
SUM(op.OP1OPVerfahren = "2") AS "Gastric Banding",
SUM(op.OP1OPVerfahren = "3") AS "Roux-en-Y Gastric Bypass",
SUM(op.OP1OPVerfahren = "99") AS "Anderes OP-Verfahren",
SUM(op.OP1OPVerfahren LIKE "%") AS "Summe"
FROM database1.dat_patient p
LEFT OUTER JOIN database1.dat_optherapie op ON op.patID = p.ID
WHERE op.OP1Datum BETWEEN "2019-01-01" AND "2019-12-31"
AND p.Testzwecke = 0
AND NOT EXISTS (SELECT 1
FROM database1.dat_optherapie op2
WHERE op2.patID = p.ID AND op2.revision > op.revision
)
UNION ALL
SELECT
SUM(op.OP1OPVerfahren = "0") AS "Keine Operation durchgeführt",
SUM(op.OP1OPVerfahren = "1") AS "Bioenterics Intragastric Ballon (BIB)",
SUM(op.OP1OPVerfahren = "2") AS "Gastric Banding",
SUM(op.OP1OPVerfahren = "3") AS "Roux-en-Y Gastric Bypass",
SUM(op.OP1OPVerfahren = "99") AS "Anderes OP-Verfahren",
SUM(op.OP1OPVerfahren LIKE "%") AS "Summe"
FROM database2.dat_patient p
LEFT OUTER JOIN database2.dat_optherapie op ON op.patID = p.ID
WHERE op.OP1Datum BETWEEN "2019-01-01" AND "2019-12-31"
AND p.Testzwecke = 0
AND NOT EXISTS (SELECT 1
FROM database2.dat_optherapie op2
WHERE op2.patID = p.ID AND op2.revision > op.revision
)
UNION ALL
[... many more identical SQL queries for other databases ...]
UNION ALL
SELECT
SUM(op.OP1OPVerfahren = "0") AS "Keine Operation durchgeführt",
SUM(op.OP1OPVerfahren = "1") AS "Bioenterics Intragastric Ballon (BIB)",
SUM(op.OP1OPVerfahren = "2") AS "Gastric Banding",
SUM(op.OP1OPVerfahren = "3") AS "Roux-en-Y Gastric Bypass",
SUM(op.OP1OPVerfahren = "99") AS "Anderes OP-Verfahren",
SUM(op.OP1OPVerfahren LIKE "%") AS "Summe"
FROM database50.dat_patient p
LEFT OUTER JOIN database50.dat_optherapie op ON op.patID = p.ID
WHERE op.OP1Datum BETWEEN "2019-01-01" AND "2019-12-31"
AND p.Testzwecke = 0
AND NOT EXISTS (SELECT 1
FROM database50.dat_optherapie op2
WHERE op2.patID = p.ID AND op2.revision > op.revision
)
GROUP BY OP1OPVerfahren;
此 SQL 代码为每个中心而不是所有中心提供 SUMmed 记录集。后者是我想要达到的。
在实验上,我根据上面的精炼代码对 SQL 查询进行了一些更改:
SELECT
SUM("Keine Operation durchgeführt"),
SUM("Bioenterics Intragastric Ballon (BIB)"),
SUM("Gastric Banding"),
SUM("Roux-en-Y Gastric Bypass"),
SUM("Anderes OP-Verfahren"),
SUM("Summe")
FROM (
SELECT
SUM(op.OP1OPVerfahren = "0") AS "Keine Operation durchgeführt",
SUM(op.OP1OPVerfahren = "1") AS "Bioenterics Intragastric Ballon (BIB)",
SUM(op.OP1OPVerfahren = "2") AS "Gastric Banding",
SUM(op.OP1OPVerfahren = "3") AS "Roux-en-Y Gastric Bypass",
SUM(op.OP1OPVerfahren = "99") AS "Anderes OP-Verfahren",
SUM(op.OP1OPVerfahren LIKE "%") AS "Summe"
FROM ods01.dat_patient p
LEFT OUTER JOIN ods01.dat_optherapie op ON op.patID = p.ID
WHERE op.OP1Datum BETWEEN "2019-01-01" AND "2019-12-31"
AND p.Testzwecke = 0
AND NOT EXISTS (SELECT 1
FROM ods01.dat_optherapie op2
WHERE op2.patID = p.ID AND op2.revision > op.revision
)
UNION ALL
SELECT
SUM(op.OP1OPVerfahren = "0") AS "Keine Operation durchgeführt",
SUM(op.OP1OPVerfahren = "1") AS "Bioenterics Intragastric Ballon (BIB)",
SUM(op.OP1OPVerfahren = "2") AS "Gastric Banding",
SUM(op.OP1OPVerfahren = "3") AS "Roux-en-Y Gastric Bypass",
SUM(op.OP1OPVerfahren = "99") AS "Anderes OP-Verfahren",
SUM(op.OP1OPVerfahren LIKE "%") AS "Summe"
FROM ods02.dat_patient p
LEFT OUTER JOIN ods02.dat_optherapie op ON op.patID = p.ID
WHERE op.OP1Datum BETWEEN "2019-01-01" AND "2019-12-31"
AND p.Testzwecke = 0
AND NOT EXISTS (SELECT 1
FROM ods02.dat_optherapie op2
WHERE op2.patID = p.ID AND op2.revision > op.revision
)
UNION ALL
SELECT
SUM(op.OP1OPVerfahren = "0") AS "Keine Operation durchgeführt",
SUM(op.OP1OPVerfahren = "1") AS "Bioenterics Intragastric Ballon (BIB)",
SUM(op.OP1OPVerfahren = "2") AS "Gastric Banding",
SUM(op.OP1OPVerfahren = "3") AS "Roux-en-Y Gastric Bypass",
SUM(op.OP1OPVerfahren = "99") AS "Anderes OP-Verfahren",
SUM(op.OP1OPVerfahren LIKE "%") AS "Summe"
FROM ods03.dat_patient p
LEFT OUTER JOIN ods03.dat_optherapie op ON op.patID = p.ID
WHERE op.OP1Datum BETWEEN "2019-01-01" AND "2019-12-31"
AND p.Testzwecke = 0
AND NOT EXISTS (SELECT 1
FROM ods03.dat_optherapie op2
WHERE op2.patID = p.ID AND op2.revision > op.revision
)
GROUP BY OP1OPVerfahren
) aftershave
-- GROUP BY OP1OPVerfahren;
如果我同时采用 UNIONed 子查询和每个子查询,它们会显示正确的结果。但是主 SQL 查询级别上的 SUM,即。 e.不在子查询中,每个总和只显示“0”。
【问题讨论】:
-
1 = 1旧的 SQL 习惯意味着总是1,你可以放心地删除它 -
此外,您不能在 SQL 中将非聚合列 (
ub.Krankenhaus AS "Zentrum") 与聚合列混合,MySQL 允许这些错误语法,除非您正在运行 sql_modeONLY_FULL_GROUP_BY.. 我建议您阅读 @ 987654322@ 并提供(混淆)示例数据和预期结果。 -
@RaymondNijland 会说同样的话。打败我。
-
是的,@RaymondNijland,谢谢,“1 = 1”我应该替换为“blah”,因为这只是进一步 WHERE 内容的占位符。我知道你的第二个感叹词,我在这里描述它是为了更好地理解中心的区别。
-
谢谢@TheImpaler,但它并没有解决核心问题。