简体   繁体   English

将多个 SQL 语句组合在一起

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM