Скажем, у меня есть три таблицы в моей базе данных:
CREATE TABLE `users` (
`user_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR(16) NOT NULL
);
CREATE TABLE `users_meta` (
`meta_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`key` VARCHAR(200) NOT NULL ,
`value` TEXT NOT NULL
);
CREATE TABLE `posts` (
`post_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`content` TEXT NOT NULL
);
Таблица users_meta - это просто хранилище информации о значении ключа для пользователей, так что мы можем добавить любую желаемую информацию.
Скажем, я добавил пару ключ = > значение в таблицу users_meta для каждого пользователя, где ключ был "age", а значение было числом, представляющим их возраст.
Учитывая этот набор обстоятельств, какой лучший способ выбрать первые 10 сообщений, упорядоченных по возрасту пользователя?
Мне нравится ставить условие соединения в самом соединении, чтобы было ясно, что я хочу ограниченное соединение:
SELECT p.post_id, p.content
FROM users u
INNER JOIN users_meta um
ON (u.user_id = um.user_id) AND um.key = 'age'
INNER JOIN posts p
ON (p.user_id = u.user_id)
ORDER BY um.value
limit 10
Если вы заказываете только по возрасту пользователя, вы выберете 10 сообщений одного пользователя (самого младшего).
Я бы предложил денормализовать и хранить возраст в таблице пользователей напрямую.
Согласитесь с @KOHb, но если это именно то, что вы хотите, вот запрос:
SELECT TOP 10 p.id, p.content
FROM users u JOIN users_meta um ON (u.user_id = um.user_id)
JOIN posts p ON (p.user_id = u.user_id)
WHERE um.key = 'age'
ORDER BY um.value