MySQL查询:从matches表中获取所有匹配项,并从teams表中获取团队名称,如果…
我有以下表格结构: 匹配项:MySQL查询:从matches表中获取所有匹配项,并从teams表中获取团队名称,如果…,sql,mysql,Sql,Mysql,我有以下表格结构: 匹配项: +-------------------+---------------------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +--------
+-------------------+---------------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------------------+------+-----+-------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| creator_id | bigint(20) | NO | | NULL | |
| mode | enum('versus','freeplay') | NO | | NULL | |
| name | varchar(100) | NO | | NULL | |
| team_1_id | varchar(100) | NO | | NULL | |
| team_2_id | varchar(100) | NO | | NULL | |
+-------------------+---------------------------+------+-----+-------------------+-----------------------------+
小组:
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| creator_id | bigint(20) | NO | MUL | NULL | |
| name | varchar(100) | NO | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
我需要一个查询,其中我们从matches表中获取所有比赛以及团队表中的团队名称,因为当模式为VS时,团队名称从团队表中获取,但当模式为freeplay时,团队名称为team_1_id或team_2_id,他们可以保留字符串,这就是为什么它们是varchar而不是int,而不进入teams表。首先,我建议您稍微更改一下表结构。不要将team_X_id用作名称或id,而应仅用于id。为team_X_名称添加一列,您可以将字符串放入其中。这样,您就可以定义外键并拥有正确的数据类型。在freeplay模式下,将team_X_id字段设置为null,将team_X_名称设置为team name,并在VS模式下将team_X_id设置为team id 也就是说,这应该满足您的要求:
SELECT mode,
IF(team_1.id IS NULL, team_1_id, team_1.name),
IF(team_2.id IS NULL, team_2_id, team_2.name),
FROM matches
LEFT JOIN teams AS team_1 ON (matches.team_id_1=team_1.id)
LEFT JOIN teams AS team_2 ON (matches.team_id_2=team_2.id);
编辑:
事实上,也许我误解了设计。如果您说模式“freeplay”标志意味着两个团队id都不是实际的团队id,那么您需要一个稍微不同的查询:
SELECT mode,
IF(mode = 'freeplay' OR team_1.id IS NULL, team_1_id, team_1.name),
IF(mode = 'freeplay' OR team_2.id IS NULL, team_2_id, team_2.name),
FROM matches
LEFT JOIN teams AS team_1 ON (matches.team_id_1=team_1.id)
LEFT JOIN teams AS team_2 ON (matches.team_id_2=team_2.id);
但我强烈建议您改进DB设计。选择CASE模式,然后选择t1.name ELSE团队_1_id以比赛名称结尾 左键在t1上加入团队t1。id=团队1\U id 对第2组执行同样的操作,并添加where子句以满足您的需要使用:
SELECT m.id,
m.creator_id,
m.mode,
m.name,
m.team_1_id,
m.team_2_id
FROM MATCHES m
WHERE m.mode = 'freeplay'
UNION ALL
SELECT m.id,
m.creator_id,
m.mode,
m.name,
t1.name,
t2.name
FROM MATCHES m
LEFT JOIN TEAMS t1 ON t1.id = m.team_1_id
LEFT JOIN TEAMS t2 ON t2.id = m.team_2_id
WHERE m.mode = 'versus'
你是说你的字段根据存储的内容有不同的含义?如果是这样的话,也许你不应该询问SQL查询,而应该询问如何重新设计数据库的提示。对于这个不相关的问题,我深表歉意,但我一直想知道如何创建/生成一个像上面两个帖子一样的纯文本表图?FreekOne-Descripte TableName将返回数据。如果您运行的是MySQL命令行客户端,它将以此处所示的样式显示。我更喜欢显示CREATE TABLE personal,因为它提供了关于表的更完整信息。如果模式为vs,您如何知道要显示的团队名称?感谢您的帮助,但查询的问题是,当模式为“freeplay”时,连接不可能,因为team_1_id将包含一个名称字符串,而不是指向team表的外键。这就是使用左连接的原因。这也是为什么桌子的设计应该改进的原因。非常感谢。。。这个查询似乎有效。。。但我有一个问题。。。当我一次分页10行查询时,这会影响性能吗?这个表大约有10万条生产记录……GeekTantra:为了获得更好的性能,您需要处理表结构。要么将团队名称存储在MATCHES表中,要么将各自的团队id列设置为INTs,因为INTs比VARCHAR4+快,这样就不需要联合。