[英]Combining multiple SQL statements together
This may be a question that has been asked already, however, I have a very peculiar database structure which I have to query efficiently by combining multiple tables by various conditions.这可能是一个已经被问过的问题,但是,我有一个非常特殊的数据库结构,我必须通过按各种条件组合多个表来有效地查询它。 It is a very bad database architecture that I did not create and cannot change, unfortunately.不幸的是,这是一个非常糟糕的数据库架构,我没有创建也无法更改。
First of all, I have a generic query that will retrieve me basic information about a 'map'首先,我有一个通用查询,它将检索我关于“地图”的基本信息
SELECT * FROM ck_maptier as z WHERE NOT EXISTS (SELECT * FROM ck_zones as cm WHERE z.mapname = cm.mapname)
The second query is supposed to get further information about a 'map'.第二个查询应该获得有关“地图”的更多信息。 I am positive that the way it is currently written is probably not great in terms of performance.我很肯定它目前的编写方式在性能方面可能不是很好。
SELECT
bonuses.count AS bonuses,
stages.count AS stages,
completions.count AS completions
FROM
(
SELECT zonegroup AS count
FROM ck_zones
WHERE mapname='<mapname>'
ORDER BY zonegroup
DESC LIMIT 1
) AS bonuses,
(
SELECT COUNT(*) AS count
FROM ck_zones
WHERE mapname='<mapname>'
AND zonetype='3'
) AS stages,
(
SELECT COUNT(mapname) AS count
FROM ck_playertimes
WHERE mapname='<mapname>'
) AS completions;
The question now is whether it is possible to combine the two into one efficient query.现在的问题是是否可以将两者结合为一个有效的查询。 I have not touched SQL in a while and cannot figure it out.我有一段时间没有接触过 SQL 并且无法弄清楚。
SHOW CREATE TABLE ck_maptier;
CREATE TABLE `ck_maptier` (
`mapname` varchar(54) NOT NULL,
`tier` int(12) NOT NULL,
`maxvelocity` float NOT NULL DEFAULT '3500',
`announcerecord` int(11) NOT NULL DEFAULT '0',
`gravityfix` int(11) NOT NULL DEFAULT '1',
`ranked` int(11) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
SHOW CREATE TABLE ck_zones;
CREATE TABLE `ck_zones` (
`mapname` varchar(54) NOT NULL,
`zoneid` int(12) NOT NULL DEFAULT '-1',
`zonetype` int(12) DEFAULT '-1',
`zonetypeid` int(12) DEFAULT '-1',
`pointa_x` float DEFAULT '-1',
`pointa_y` float DEFAULT '-1',
`pointa_z` float DEFAULT '-1',
`pointb_x` float DEFAULT '-1',
`pointb_y` float DEFAULT '-1',
`pointb_z` float DEFAULT '-1',
`vis` int(12) DEFAULT '0',
`team` int(12) DEFAULT '0',
`zonegroup` int(11) NOT NULL DEFAULT '0',
`zonename` varchar(128) DEFAULT NULL,
`hookname` varchar(128) DEFAULT 'None',
`targetname` varchar(128) DEFAULT 'player',
`onejumplimit` int(12) NOT NULL DEFAULT '1',
`prespeed` int(64) NOT NULL DEFAULT '350',
PRIMARY KEY (`mapname`,`zoneid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
SHOW CREATE TABLE ck_playertimes;
CREATE TABLE `ck_playertimes` (
`steamid` varchar(32) NOT NULL,
`mapname` varchar(32) NOT NULL,
`name` varchar(32) DEFAULT NULL,
`runtimepro` float NOT NULL DEFAULT '-1',
`style` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`steamid`,`mapname`,`style`),
KEY `maprank` (`mapname`,`runtimepro`,`style`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
My desired output from a single query is我从单个查询中想要的 output 是
| mapname | tier | bonuses | stages | completions |
| surf_3 | 3 | 6 | 5 | 256 |
Rearrange things:重新排列东西:
SELECT
(
SELECT zonegroup AS count
FROM ck_zones
WHERE mapname='<mapname>'
ORDER BY zonegroup
DESC LIMIT 1
) AS bonuses,
(
SELECT COUNT(*) AS count
FROM ck_zones
WHERE mapname='<mapname>'
AND zonetype='3'
) AS stages,
(
SELECT COUNT(mapname) AS count
FROM ck_playertimes
WHERE mapname='<mapname>'
) AS completions;
Add some indexes:添加一些索引:
ck_zones: INDEX(mapname, zonegroup) -- in this order
ck_zones: INDEX(mapname, zonetype) -- either order is OK
ck_playertimes: INDEX(mapname) -- handled by your `maprank`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.