Собственно говоря столкнулся с одной проблемкой, необходимо получить данные в один запрос. Суть дела такова что есть 3 таблицы: 1) Soft - содержит имя софта и номер id INT PRIMARY KEY name VARCHAR(32) 2) Langs - содержит инфу о языке id INT PRIMARY KEY name VARCHAR(32) // имя языка main INT // главный или нет если main = 1 значит язык является главным. main = 1 есть только у одного языка и всегда присутствует. 3) Info - содержит описание софта id INT PRIMARY KEY soft_id INT FOREIGN KEY REFERENCES Soft(id) lang_id INT FOREIGN KEY REFERENCES Langs(id) data TEXT т.е. структура такая: Langs - список языков, Soft - список софта, Info - инфа о софте, на разных языках. И вот основная проблема: необходимо выбрать данных из Info зная soft_id и lang_id, но если в таблице отсутствует описание для указанного lang_id, то брать описание для языка у которого main = 1. И всё это необходимо провернуть в один запрос. Пытался завернуть всё в хранимую процедуру, но результат чуть не тот получается. Да и желательно без хранимых процедур. Даже не представляю как это завернуть в один запрос. Пытался по быдлокодовки написать чтото типа: Code: SELECT * FROM `Info` WHERE `soft_id` = НОМЕР_СОФТА HAVING `lang_id` = НОМЕР_ЯЗЫКА OR `lang_id`=(SELECT `id` FROM `langs` WHERE `main` = 1) Но такая конструкция пашет только если указан не найденный НОМЕР_ЯЗЫКА.
Единственный рабочий вариант который я придумал это только Code: SELECT * FROM `Info` WHERE `soft_id` = НОМЕР_СОФТА AND `lang_id`=НОМЕР_ЯЗЫКА UNION SELECT * FROM `Info` WHERE `soft_id` = НОМЕР_СОФТА AND `lang_id`=(SELECT `id` FROM `Langs` WHERE `main`=1) LIMIT 1 Но увы это самое полное извращение. Или даже так записать Code: SELECT * FROM `Info` WHERE `soft_id` = НОМЕР_СОФТА AND `lang_id`=НОМЕР_ЯЗЫКА UNION SELECT `Info`.* FROM `Info`, `Langs` WHERE `soft_id` = НОМЕР_СОФТА AND `Info`.`lang_id`=`Langs`.`id` AND `Langs`.`main`=1 LIMIT 1 Но всё равно это не оптимизированное извращение выходит.
slesh Code: SELECT * FROM `Info` WHERE `soft_id`=1 AND (`lang_id` in (SELECT `id` FROM `langs` WHERE `lang_id` = 1 or `main` = 1 ORDER BY `main` desc));
Code: SELECT Soft.name, Langs.name, Info.data FROM Info INNER JOIN Langs ON Info.lang_id = Langs.id INNER JOIN Soft ON Info.soft_id = Soft.id WHERE (Info.soft_id = 2) AND (Info.lang_id = 6 OR Info.lang_id = (SELECT main_lang_id FROM Soft WHERE Soft.id = 2)) Запрос вернет 1+ строк. В первой будет нужная инфа. main_lang_id - колнка в таблице Soft с главным языком приложения. Из таблицы lang его можно удалить.
Решил не париться с делать чуть по другому: Первый язык в таблице Langs - главный. И выборка идет по типу: SELECT * FROM Info WHERE soft_id = НОМЕР_СОФТА AND (lang_id = НОМЕР_ЯЗЫКА OR lang_id=1) ORDER BY lang_id DESC LIMIT 1 По любому будет получено 1 значение из базы которое будет или ножным языком или первым языком