简体   繁体   中英

SQL OUTER JOIN with empty fields (null) where no result

Hulloes SO!

Okay, so my case is this: I have a db where I need to SELECT from 4 different tables and get results where my foregin keys in one table matches the ids in my other 3 tables.

Structure:

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;

The translations table is the table with all the relations ( translations.project => project.id , translations.key => main_keys.id , and translations.language => language.id ).

Relational overview http://assets.brianemilius.com/locale_relations.png

My current query looks like this

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'

I am selecting from a specific project(p.id) and a specific language(l.id) and I want a result, which shows something like this:

+----+--------------+-------------+---------------------------+-----------------------+---------------------+
| 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  |                     |
+----+--------------+-------------+---------------------------+-----------------------+---------------------+

Where rows 2 and 3 represent results where there are no translations.

But I only get 1 row result - the top one with id 2 (because there currently only is one translation row in the table translations ).

I've tried various combinations of LEFT and RIGHT JOIN in my query, but nothing seems to help. Am I on track or do I need to completely rethink?

I think you need to rethink a bit and use the main_keys table as the main source and left join the other 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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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