Всем добра! Не могу победить, выручайте! Есть две таблицы: задания (zadan) и выполнение юзерами (zadan_user) заданий. 1) id, name, text, status 2) id, id_zadanie, user, user_id id_zadanie = id Заданий допустим 4шт, а выполнений юзерами много. И при вывод задания дублируются. Пробовал вот так: Код (Text): $sql = 'SELECT * FROM zadan LEFT JOIN zadan_user ON zadan.id = zadan_user.id_zadanie WHERE zadan.status = 0 ORDER BY zadan.id DESC'; $sql = 'SELECT * FROM zadan, zadan_user WHERE zadan.status = 0 AND zadan.id = zadan_user.id_zadanie ORDER BY zadan.id DESC'; $sql = 'SELECT * FROM zadan LEFT OUTER JOIN zadan_user ON zadan.id = zadan_user.id_zadanie where zadan_user.id is null'; Пробовал и RIGHT JOIN и OUTER... Где косяк? Почему дублируются задания при выводе? Спасибо!
@webog, сформулируйте точнее, что в результате запроса хотите получить. А join работает так, как и должен. Подробности.
Код (Text): SELECT `q`.`id`, `q`.`name`, `q`.`text`, `q`.`status`, `u`.`id_zadanie`, `u`.`user`, `u`.`user_id` FROM `zadan` AS `q` LEFT JOIN `zadan_user` AS `u` ON ( `q`.`id` = `u`.`id_zadanie` ) WHERE `u`.`user_id`=? ORDER BY `u`.`id_zadanie` DESC Только у тебя логика таблиц явно нарушена. В заданиях держишь все, наименование, текст, айди В заданиях взятых или выполненных юзером держишь только айди задания и его статус выполнения, возможно ещё требования)
всё правильно, книжки пишут лохи исключительно для лохов, ты выше этого, продолжай своим темам давать такие громкие названия (можно даже побольше матершины для эффекта) и тогда ты станешь как они -> https://xakep.ru/2001/06/19/12860/
@lastdays вывелось (по примеру) только те задания который выполнил данный юзер. Нужно еще вывести те которые не выполнил (все нужно вывести) --- Добавлено --- Времени нет читать хакер ) Книжек нет, манны курил - не получается. Видимо нужен изощренный способ и явно JOIN'ы сюда не подходят. --- Добавлено --- UPD: Если брать INNER JOIN, то вообще выводит(дублирует) задания столько раз сколько юзеров их выполнили. LEFT JOIN ведет себя так же.
Тогда таблицы должны (могут) быть такими: id юзера, фио юзера (разделенные или нет на отдельные поля имя, фамилия... и, возможно, некоторые другие данные юзера) id задания, текст задания id юзера, id задания, статус выполнения задания юзером То есть, сначала пользователю назначаются задания и по мере выполнения в соответствующей таблице меняется статус выполнения задания юзером. Если юзер авторизован, то, соответственно, ему выводите список только его заданий. И тот самый статус выполнения... Либо вообще все задания и статус выполнения его авторизованным юзером, либо без вывода статуса, если задание не назначено данному юзеру. Тут уж как задумано... Пока что всё верно?
@webog, не в этом дело. Ты реально пытаешься построить дом не имея фундамента. В большинстве случаев ты решаешь проблемы, которые вообще не нужно себе создавать. Помнишь мультфильм "лучше день потерять, потом за пять минут долететь"? Так и тут, потратив немного времени на чтение книг, ты сэкономишь тонны этого самого времени не создавая себе проблем. Джоины нужны обязательно и не только они, скорее всего тебе ещё и USING нужен. Но надо чётко представлять задачу, а без базовых знаний это сделать практически невозможно.
Да, но... ... вот тут нужно если авторизован выводятся все задания(вот прям все что есть), но под каждым заданием статус относительно юзера выполнил его или нет. --- Добавлено --- Уйди пожалуйста, если больше нечего сказать по делу! Только отвлекаешь меня и других.
Тогда выполняется выборка из таблицы заданий с left join из таблицы прицепленных к юзерам заданий с ограничением (where) по id конкретного юзера. В этом случае в выборке для заданий, которые не закреплены за конкретным пользователем соответствующие поля будут иметь значение null (потому и left join)
@Sail что бы не быть голословным, вот скрин http://prntscr.com/l58ilm На варчары можно не обращать внимания (делал на скорую руку для демо), в базе у меня int. http://sqlfiddle.com/#!9/a0ed2a/1/10 вот прошу LEFT JOIN - http://sqlfiddle.com/#!9/a0ed2a/2 скрин http://prntscr.com/l58ngs Как этот дубль убрать?
@webog, ещё раз: "с ограничением (where) по id конкретного юзера". Во-вторых: для чего в таблице quests_user под id 2 и 3 записаны одинаковые данные? --- Добавлено --- @webog, но если вдруг религия не позволит привести в порядок ту таблицу, то нужно "джойнить" не с самой таблицей, а с соотнесенным подзапросом по той таблице. Наподобие выборки, представленной для случая. Не обращать внимания на агрегатные функции, и обратить внимание на слово distinct в подзапросе и псевдоним подзапроса...
Очепятка, поправил, но результат то же! Дублируется http://prntscr.com/l58vvl Код (Text): INSERT INTO quests_user (id_quest, id_user, status_user) VALUES ('1', '3', '0'), ('2', '4', '0'), ('2', '5', '0'); Это типо (cтатус у всех равен нулю): задание ID 1 выполнил юзер ID 3 задание ID 2 выполнил юзер ID 4 задание ID 2 выполнил юзер ID 5 --- Добавлено --- Позволяет! Как нужно?
@webog, вот теперь осталось добавить where id_user = id залогиненного (этого) юзера. И использовать left join
@Sail круто, но вывелось то задание которое этот залогиненый юзер выполнил. http://prntscr.com/l58zif Нужно что бы все 100 заданий выводились и лишь под теми которые выполнены юзером ставить статус выполнено или нет.
@Sail уже ближе к истине, но не выводится одно задание. Не пойму по чему. Есть юзеры которые выполняли его, но оно не выводится. В общем не то http://prntscr.com/l59zpg Есть еще варианты?
@webog, ну да, тот самый случай Код (Text): select * from quests q left join (select id_quest from quests_user where id_user = 5) as qu on qu.id_quest = q.id;
@webog, а ведь ограничение выборки по id юзера можно включить в условие объединения: Код (Text): select * from quests q left join quests_user qu on qu.id_quest = q.id and qu.id_user = 5; P.S. Это ведь не фриланс.