powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / JOIN и WHERE
19 сообщений из 19, страница 1 из 1
JOIN и WHERE
    #39935375
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет,

Есть две связанные таблицы, например упрощенно

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
materials 
  mat_id int(11)
  mat_name varchar(512)
  mat_tch_test_folder_id varchar(1024)
  mat_tch_test_type varchar(3)
  mat_tch_test_name varchar(1024)
  
mat_details (
  mthd_id int(11)
  mthd_file_id varchar(255)
  mthd_mat_id int(11) - это mat_id из родительской записи
  mthd_test int(11)   - уровень теста, может быть от 1 до 5



Нужно получить mat_tch_test_type из родительской таблицы materials, где есть в дочерней таблице тесты, например уровня 1.

Сделал два варианта, вроде работают. Какой из них правильный и более предпочтительный.

Вариант 1
Код: sql
1.
2.
3.
4.
  SELECT mat_tch_test_type
  FROM materials
    JOIN mat_details ON mat_id = mthd_mat_id
  WHERE mthd_mat_id = mat_id AND mthd_test = 1 LIMIT 1;



Вариант 2
Код: sql
1.
2.
3.
4.
  SELECT mat_tch_test_type 
  FROM mat_details
    JOIN materials ON mthd_mat_id = mat_id
  WHERE mthd_mat_id = mat_id AND mthd_test = 1 LIMIT 1;
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935410
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оба варианта совершенно одинаковые (на 100%)
предпочтительнее первый, где родительская "слева", "справа" привязываем подчиненную.

Возможно для "левшей" удобнее второй вариант, у них полушария по другому работают.
Я правша...
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935412
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savsoft,

Порядок перечисления таблиц в JOIN-е значения не имеет. По крайней мере до тех пор, пока этих таблиц в запросе становится не слишком много и пока оптимизатор в силах перебрать все комбинации их соединения.

В WHERE не надо повторять условия соединения из JOIN. В случае простого JOIN это бессмысленно, а в случае LEFT JOIN даже вредно.

LIMIT 1 даст какую-то одну запись, без определенности какую именно и даже без гарантии повторяемости.

У полей в запросе очень желательно явно указывать имена или алиасы таблиц, иначе для стороннего человека читабельность запроса резко падает.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935414
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft
savsoft,
LIMIT 1 даст какую-то одну запись, без определенности какую именно и даже без гарантии повторяемости.


По условию, к одной родительской записи могут быть прицеплены дочерние только одного типа. Поэтому поставил LIMIT 1.

miksoft
savsoft,
У полей в запросе очень желательно явно указывать имена или алиасы таблиц, иначе для стороннего человека читабельность запроса резко падает.


Я использую уникальные префиксы полей, но для читабельности нужно использовать имена или алиасы. Поправлю.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935415
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо за помощь,
буду дальше изучать JOINs.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935417
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savsoft
По условию, к одной родительской записи могут быть прицеплены дочерние только одного типа. Поэтому поставил LIMIT 1.
LIMIT действует на результат всего запроса, а не на количество приджойненных записей к каждой "ведущей" записи.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935418
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savsoft
Я использую уникальные префиксы полей
Когда таблиц будут хотя бы сотни, это не поможет.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935419
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savsoft , поскольку используется просто JOIN, который по факту INNER JOIN, порядок таблиц неважен. Но всё изменится, если нужно использовать внешнее связывание (LEFT JOIN) - тут порядок будет критичен.

Впрочем, всегда старайтесь таблицы со стороны "один" располагать раньше по тексту, чем таблицы со стороны "много".

savsoft
По условию, к одной родительской записи могут быть прицеплены дочерние только одного типа. Поэтому поставил LIMIT 1.

Что бы, какие зависимости, не были закопаны в конкретных данных, это не должно влиять на запрос. В данном случае схема не запрещает существования нескольких записей, соответствующих условиям отбора. А в этом случае ОБЯЗАТЕЛЬНО наличие ORDER BY, причём по уникальному выражению - в противном случае запрос получается недетерминированным, и два его выполнения на одних и тех же данных могут дать разные результаты , что в общем ни в какие ворота...
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935429
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Значит в итоге получается такой запрос в функции

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
FUNCTION is_tch_mat_test_exists(matID int)
  RETURNS varchar(3) CHARSET utf8
BEGIN

  DECLARE Test varchar(3) DEFAULT '';

  SELECT
    mat_tch_test_type INTO Test
  FROM materials
    JOIN mat_tch_details ON mat_id = mthd_mat_id
  WHERE mthd_mat_id = matID
  AND mthd_test = 1 
  ORDER BY mthd_id LIMIT 1;

  RETURN Test;

END
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935437
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savsoft,

а функция-то зачем?
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935445
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

Есть таблица учебных материалов, к которым есть материалы учителя и, возможно, материалы тестов. Заполняю таблицу материалов и функцией определяю, есть ли тесты. Если есть, то иконка тестов, иначе пустая иконка.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935458
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savsoft,

Подозреваю, что вам нужно использовать EXISTS вместо функции.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935465
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft
savsoft,

Подозреваю, что вам нужно использовать EXISTS вместо функции.


Мне нужна инфа о существовании тестов в результате селекта, а не в условиях. Типа

Код: sql
1.
2.
SELECT mat_id, mat_name, mat_tch_test_name, is_tch_mat_test_exists(mat_id)
FROM materials;
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935491
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savsoft
Мне нужна инфа о существовании тестов в результате селекта, а не в условиях.
Тогда тем более
miksoft
нужно использовать EXISTS вместо функции

... в списке вывода.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935500
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
savsoft
Мне нужна инфа о существовании тестов в результате селекта, а не в условиях.
Тогда тем более
miksoft
нужно использовать EXISTS вместо функции

... в списке вывода.


И как это написать? Я только нашел примеры EXISTS в условии WHERE.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935588
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
SELECT EXISTS (подзапрос) AS имя_поля, ...

Вернёт соответственно 0 или 1.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935591
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savsoft,

начнем со слов "едрить-мадрить")))
такой функции обычно не требуется... ну да ладно...
обычно такое требуется при построении интерфейса, допустим в вэб
сразу вместе с данными получаем список, вместе с принадлежностью - есть тесты или нет, чтобы отрисовать "значок-ярлычок"

Код: sql
1.
2.
3.
4.
5.
6.
SELECT
    mat_tch_test_type
FROM materials
    LEFT JOIN mat_tch_details ON mat_id = mthd_mat_id  AND mthd_test = 1 

  


LEFT JOIN - показывает все записи из родительской таблицы, условия в ON не отрубают записи c таблицы "слева" ,
если укажем условия в WHERE - то превратим LEFT JOIN в INNER JOIN, условие в WHERE будет применено и к родительской таблице "слева" .
Вот такая разница между условием в ON и в WHERE
т.е. чтобы получить все "разом" - можем сделать так
Код: sql
1.
2.
3.
4.
5.
6.
SELECT
    materials.*, IF(ISNULL(mat_tch_details),0,1)) as "1=Yes"
FROM materials
    LEFT JOIN mat_tch_details ON mat_id = mthd_mat_id  AND mthd_test = 1 

  


и вместе с данными можем отрисовать ярлыки, а не дергать функцию на каждую строку...
... однако выходной....
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935598
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina
Код: sql
1.
SELECT EXISTS (подзапрос) AS имя_поля, ...

Вернёт соответственно 0 или 1.


Спасибо, работает в разы быстрее, чем с функцией.
...
Рейтинг: 0 / 0
JOIN и WHERE
    #39935599
savsoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex_Ustinov,

Спасибо, буду пробовать.
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / JOIN и WHERE
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]