SQL 带有空字段 (null) 的 OUTER JOIN,其中没有结果
SQL OUTER JOIN with empty fields (null) where no result
你好!
好的,所以我的情况是这样的:我有一个数据库,我需要从 4 个不同的 table 中 SELECT 并得到结果,其中一个 table 中的外键匹配我的其他 3 tables.
中的 ID
结构:
CREATE TABLE IF NOT EXISTS `languages` (
`id` int(11) NOT NULL,
`lang_name` varchar(64) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `main_keys` (
`id` int(11) NOT NULL,
`project` int(11) NOT NULL,
`key` text COLLATE utf8_bin NOT NULL,
`comment` varchar(128) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `projects` (
`id` int(11) NOT NULL,
`project_name` varchar(64) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `translations` (
`id` int(11) NOT NULL,
`project` int(11) NOT NULL,
`key` int(11) NOT NULL,
`language` int(11) NOT NULL,
`translation` text COLLATE utf8_bin NOT NULL,
`lastedit` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
translations
table 是 table 与所有关系 (translations.project
=> project.id
, translations.key
=> main_keys.id
, 和 translations.language
=> language.id
).
Relational overview http://assets.brianemilius.com/locale_relations.png
我当前的查询如下所示
SELECT t.id, mk.key, t.translation, mk.comment, p.project_name, t.lastedit
FROM translations t
INNER JOIN languages l ON l.id = t.language
INNER JOIN main_keys mk ON mk.id = t.key
INNER JOIN projects p ON p.id = mk.project
WHERE p.id = '1' AND l.id = '2'
我正在从特定项目 (p.id) 和特定语言 (l.id) 中进行选择,我想要一个结果,它显示如下内容:
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| id | key | translation | comment | project_name | lastedit |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| 2 | Hello World! | Hej verden! | Test key for dev purposes | Locale Administrator | 2015-02-24 12:37:28 |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| | test key | | Test key for dev purposes | Locale Administrator | |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| | test key 2 | | Test key for dev purposes | Locale Administrator | |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
第 2 行和第 3 行表示没有翻译的结果。
但我只得到 1 行结果 - id 为 2 的第一行(因为目前 table translations
中只有一个翻译行)。
我在查询中尝试了 LEFT 和 RIGHT JOIN 的各种组合,但似乎无济于事。我走上正轨还是需要彻底重新思考?
我认为你需要重新考虑一下,使用 main_keys
table 作为主要来源,然后加入其他 tables:
SELECT t.id, mk.key, t.translation, mk.comment, p.project_name, t.lastedit
FROM main_keys mk
LEFT JOIN translations t ON mk.id = t.key
LEFT JOIN languages l ON l.id = t.language
LEFT JOIN projects p ON p.id = mk.project
WHERE p.id = 1 AND l.id = 2 OR l.id IS null;
你好!
好的,所以我的情况是这样的:我有一个数据库,我需要从 4 个不同的 table 中 SELECT 并得到结果,其中一个 table 中的外键匹配我的其他 3 tables.
中的 ID结构:
CREATE TABLE IF NOT EXISTS `languages` (
`id` int(11) NOT NULL,
`lang_name` varchar(64) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `main_keys` (
`id` int(11) NOT NULL,
`project` int(11) NOT NULL,
`key` text COLLATE utf8_bin NOT NULL,
`comment` varchar(128) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `projects` (
`id` int(11) NOT NULL,
`project_name` varchar(64) COLLATE utf8_bin NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE IF NOT EXISTS `translations` (
`id` int(11) NOT NULL,
`project` int(11) NOT NULL,
`key` int(11) NOT NULL,
`language` int(11) NOT NULL,
`translation` text COLLATE utf8_bin NOT NULL,
`lastedit` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
translations
table 是 table 与所有关系 (translations.project
=> project.id
, translations.key
=> main_keys.id
, 和 translations.language
=> language.id
).
Relational overview http://assets.brianemilius.com/locale_relations.png
我当前的查询如下所示
SELECT t.id, mk.key, t.translation, mk.comment, p.project_name, t.lastedit
FROM translations t
INNER JOIN languages l ON l.id = t.language
INNER JOIN main_keys mk ON mk.id = t.key
INNER JOIN projects p ON p.id = mk.project
WHERE p.id = '1' AND l.id = '2'
我正在从特定项目 (p.id) 和特定语言 (l.id) 中进行选择,我想要一个结果,它显示如下内容:
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| id | key | translation | comment | project_name | lastedit |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| 2 | Hello World! | Hej verden! | Test key for dev purposes | Locale Administrator | 2015-02-24 12:37:28 |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| | test key | | Test key for dev purposes | Locale Administrator | |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| | test key 2 | | Test key for dev purposes | Locale Administrator | |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+
第 2 行和第 3 行表示没有翻译的结果。
但我只得到 1 行结果 - id 为 2 的第一行(因为目前 table translations
中只有一个翻译行)。
我在查询中尝试了 LEFT 和 RIGHT JOIN 的各种组合,但似乎无济于事。我走上正轨还是需要彻底重新思考?
我认为你需要重新考虑一下,使用 main_keys
table 作为主要来源,然后加入其他 tables:
SELECT t.id, mk.key, t.translation, mk.comment, p.project_name, t.lastedit
FROM main_keys mk
LEFT JOIN translations t ON mk.id = t.key
LEFT JOIN languages l ON l.id = t.language
LEFT JOIN projects p ON p.id = mk.project
WHERE p.id = 1 AND l.id = 2 OR l.id IS null;