За последние 24 часа нас посетили 23068 программистов и 1238 роботов. Сейчас ищут 886 программистов ...

Выборка из двух таблиц MySQL мать её

Тема в разделе "Сделайте за меня", создана пользователем AlexProg, 11 окт 2018.

  1. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    Всем добра!

    Не могу победить, выручайте!
    Есть две таблицы: задания (zadan) и выполнение юзерами (zadan_user) заданий.
    1) id, name, text, status
    2) id, id_zadanie, user, user_id
    id_zadanie = id

    Заданий допустим 4шт, а выполнений юзерами много. И при вывод задания дублируются.

    Пробовал вот так:
    Код (Text):
    1. $sql = 'SELECT * FROM zadan LEFT JOIN zadan_user ON zadan.id = zadan_user.id_zadanie WHERE zadan.status = 0 ORDER BY zadan.id DESC';
    2. $sql = 'SELECT * FROM zadan, zadan_user WHERE zadan.status = 0 AND zadan.id = zadan_user.id_zadanie ORDER BY zadan.id DESC';
    3. $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...

    Где косяк? Почему дублируются задания при выводе?

    Спасибо!
     
  2. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    потому, что сначала читаешь книги, а потом кодишь в тёмную голую, а у тебя всё через zadan
     
  3. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @webog, сформулируйте точнее, что в результате запроса хотите получить.
    А join работает так, как и должен. Подробности.
     
    AlexProg нравится это.
  4. lastdays

    lastdays Активный пользователь

    С нами с:
    27 сен 2012
    Сообщения:
    410
    Симпатии:
    74
    Код (Text):
    1. SELECT
    2.   `q`.`id`, `q`.`name`, `q`.`text`, `q`.`status`,
    3.   `u`.`id_zadanie`, `u`.`user`, `u`.`user_id`
    4. FROM
    5.   `zadan` AS `q`
    6. LEFT JOIN
    7.   `zadan_user` AS `u`
    8. ON ( `q`.`id` = `u`.`id_zadanie` )
    9. WHERE
    10. `u`.`user_id`=?
    11. ORDER BY `u`.`id_zadanie` DESC
    Только у тебя логика таблиц явно нарушена.

    В заданиях держишь все, наименование, текст, айди
    В заданиях взятых или выполненных юзером держишь только айди задания и его статус выполнения, возможно ещё требования)
     
    AlexProg нравится это.
  5. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    По себе людей не судят! Это у тебя все так, умник!
     
  6. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    Выводить под заданиями статус выполнения для юзера который авторизован.
    --- Добавлено ---
    Как нужно?
     
  7. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    всё правильно, книжки пишут лохи исключительно для лохов, ты выше этого, продолжай своим темам давать такие громкие названия (можно даже побольше матершины для эффекта) и тогда ты станешь как они -> https://xakep.ru/2001/06/19/12860/
     
    AlexProg нравится это.
  8. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    @lastdays вывелось (по примеру) только те задания который выполнил данный юзер. Нужно еще вывести те которые не выполнил (все нужно вывести)
    --- Добавлено ---
    Времени нет читать хакер )
    Книжек нет, манны курил - не получается. Видимо нужен изощренный способ и явно JOIN'ы сюда не подходят.
    --- Добавлено ---
    UPD: Если брать INNER JOIN, то вообще выводит(дублирует) задания столько раз сколько юзеров их выполнили. LEFT JOIN ведет себя так же.
     
  9. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Тогда таблицы должны (могут) быть такими:
    id юзера, фио юзера (разделенные или нет на отдельные поля имя, фамилия... и, возможно, некоторые другие данные юзера)
    id задания, текст задания
    id юзера, id задания, статус выполнения задания юзером
    То есть, сначала пользователю назначаются задания и по мере выполнения в соответствующей таблице меняется статус выполнения задания юзером.
    Если юзер авторизован, то, соответственно, ему выводите список только его заданий. И тот самый статус выполнения...
    Либо вообще все задания и статус выполнения его авторизованным юзером, либо без вывода статуса, если задание не назначено данному юзеру. Тут уж как задумано...
    Пока что всё верно?
     
    AlexProg нравится это.
  10. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @webog, не в этом дело. Ты реально пытаешься построить дом не имея фундамента. В большинстве случаев ты решаешь проблемы, которые вообще не нужно себе создавать. Помнишь мультфильм "лучше день потерять, потом за пять минут долететь"? Так и тут, потратив немного времени на чтение книг, ты сэкономишь тонны этого самого времени не создавая себе проблем.
    Джоины нужны обязательно и не только они, скорее всего тебе ещё и USING нужен. Но надо чётко представлять задачу, а без базовых знаний это сделать практически невозможно.
     
  11. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    Да, но...

    ... вот тут нужно если авторизован выводятся все задания(вот прям все что есть), но под каждым заданием статус относительно юзера выполнил его или нет.
    --- Добавлено ---
    Уйди пожалуйста, если больше нечего сказать по делу!
    Только отвлекаешь меня и других.
     
  12. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Тогда выполняется выборка из таблицы заданий с left join из таблицы прицепленных к юзерам заданий с ограничением (where) по id конкретного юзера.
    В этом случае в выборке для заданий, которые не закреплены за конкретным пользователем соответствующие поля будут иметь значение null (потому и left join)
     
    AlexProg нравится это.
  13. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    Пробовал так

     
  14. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    #14 AlexProg, 12 окт 2018
    Последнее редактирование: 12 окт 2018
  15. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @webog, ещё раз: "с ограничением (where) по id конкретного юзера".
    Во-вторых: для чего в таблице quests_user под id 2 и 3 записаны одинаковые данные?
    --- Добавлено ---
    @webog, но если вдруг религия не позволит привести в порядок ту таблицу, то нужно "джойнить" не с самой таблицей, а с соотнесенным подзапросом по той таблице. Наподобие выборки, представленной для случая.
    Не обращать внимания на агрегатные функции, и обратить внимание на слово distinct в подзапросе и псевдоним подзапроса...
     
    AlexProg нравится это.
  16. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    Очепятка, поправил, но результат то же! Дублируется http://prntscr.com/l58vvl

    Код (Text):
    1. INSERT INTO quests_user
    2. (id_quest, id_user, status_user)
    3. VALUES
    4. ('1', '3', '0'),
    5. ('2', '4', '0'),
    6. ('2', '5', '0');
    Это типо (cтатус у всех равен нулю):
    задание ID 1 выполнил юзер ID 3
    задание ID 2 выполнил юзер ID 4
    задание ID 2 выполнил юзер ID 5
    --- Добавлено ---
    Позволяет! Как нужно? :)
     
  17. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @webog, вот теперь осталось добавить where id_user = id залогиненного (этого) юзера. И использовать left join
     
    AlexProg нравится это.
  18. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    @Sail круто, но вывелось то задание которое этот залогиненый юзер выполнил. http://prntscr.com/l58zif

    Нужно что бы все 100 заданий выводились и лишь под теми которые выполнены юзером ставить статус выполнено или нет.
     
  19. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @webog, добавьте к условию or id_user is null
     
    AlexProg нравится это.
  20. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    @Sail уже ближе к истине, но не выводится одно задание. Не пойму по чему.
    Есть юзеры которые выполняли его, но оно не выводится.

    В общем не то http://prntscr.com/l59zpg
    Есть еще варианты? :)
     
  21. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @webog, ну да, тот самый случай :)
    Код (Text):
    1. select * from quests q left join (select id_quest from quests_user where id_user = 5) as qu on qu.id_quest = q.id;
     
    AlexProg нравится это.
  22. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    @Sail спасибо большое!
    Оно! Тему можно закрывать!

    P.S. Куда "благодарочку" скинуть?
     
  23. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @webog, а ведь ограничение выборки по id юзера можно включить в условие объединения:
    Код (Text):
    1. select * from quests q left join quests_user qu on qu.id_quest = q.id and qu.id_user = 5;
    P.S. Это ведь не фриланс.
     
    AlexProg нравится это.