powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Джойны
12 сообщений из 12, страница 1 из 1
Джойны
    #40103813
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица Приходы (incom), у нее подчиненная таблица Разгрузки (unload). Надо, чтобы отображались все приходы, но при этом разгрузки, соответствующие приходу, отображались только до определенной даты. Если нет разгрузок, удовлетворяющих условиям, то приход все равно должен отображаться.
Если без условия по датам, то понятно, вот так:
Код: sql
1.
2.
3.
4.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN unload u ON u.incom_id = i.id
GROUP BY i.id


И будут отображаться все приходы.
Но вот если по второй таблице ставим ограничение, и набор в ней оказывается пустым, то отобразится ли приход?
Код: sql
1.
2.
3.
4.
5.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN unload u ON u.incom_id = i.id
WHERE u.date_unload <= :a_date
GROUP BY i.id
...
Рейтинг: 0 / 0
Джойны
    #40103816
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или как-то так?
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN (SELECT u.incom_id 
                 FROM unload u 
                 WHERE u.date_unload <= :a_date) inner_query
    ON inner_query.incom_id = i.id
GROUP BY i.id
...
Рейтинг: 0 / 0
Джойны
    #40103848
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При внешнем связывании условия по внешней таблице следует располагать в секции ON:
Код: sql
1.
2.
3.
4.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN unload u ON u.incom_id = i.id AND u.date_unload <= :a_date
GROUP BY i.id


Ну и, чтобы NULL не получать на выходе, можно обернуть вывод суммы в COALESCE().
...
Рейтинг: 0 / 0
Джойны
    #40103852
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
При внешнем связывании условия по внешней таблице следует располагать в секции ON:
Код: sql
1.
2.
3.
4.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN unload u ON u.incom_id = i.id AND u.date_unload <= :a_date
GROUP BY i.id


Ну и, чтобы NULL не получать на выходе, можно обернуть вывод суммы в COALESCE().


Там на самом деле немного сложнее. Вторая таблица не одна, а джойнится с еще одной таблицей, и вот в ней уже указана дата. Так что надо как-то сделать вложенный джойн.
Из этого...
Код: sql
1.
2.
3.
4.
5.
6.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN unload u ON u.incom_id = i.id 
LEFT JOIN plan p ON p.id = u.plan_id
WHERE p.plan_date <= :a_date
GROUP BY i.id



P.S. И правильно ли я понимаю, что
LEFT JOIN... LEFT JOIN... при наличии WHERE теряет смысл и превращается в INNER JOIN ... INNER JOIN... WHERE
...
Рейтинг: 0 / 0
Джойны
    #40103896
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad
Там на самом деле немного сложнее. Вторая таблица не одна, а джойнится с еще одной таблицей, и вот в ней уже указана дата.

Это ничего не меняет.

svnvlad
Так что надо как-то сделать вложенный джойн.

Вроде сказал понятно - при внешнем связывании условия по внешней таблице следует располагать в секции ON... и даже показал как именно... не, мимо ушей.

svnvlad
И правильно ли я понимаю, что LEFT JOIN... LEFT JOIN... при наличии WHERE теряет смысл и превращается в INNER JOIN ... INNER JOIN... WHERE

FROM a LEFT JOIN b LEFT JOIN c WHERE a.x = :x - работает как есть.

FROM a LEFT JOIN b LEFT JOIN c WHERE b.x = :x - работает как FROM a INNER JOIN b LEFT JOIN c WHERE b.x = :x .

FROM a LEFT JOIN b LEFT JOIN c WHERE c.x = :x - работает как FROM a INNER JOIN b INNER JOIN c WHERE c.x = :x .
...
Рейтинг: 0 / 0
Джойны
    #40103952
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
svnvlad
Там на самом деле немного сложнее. Вторая таблица не одна, а джойнится с еще одной таблицей, и вот в ней уже указана дата.

Это ничего не меняет.

svnvlad
Так что надо как-то сделать вложенный джойн.

Вроде сказал понятно - при внешнем связывании условия по внешней таблице следует располагать в секции ON... и даже показал как именно... не, мимо ушей.

Так что ли?
Код: sql
1.
2.
3.
4.
5.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN unload u ON u.incom_id = i.id 
LEFT JOIN plan p ON p.id = u.plan_id AND p.plan_date <= :a_date
GROUP BY i.id


Ну и что, он соединит incom с unload в любом случае (и посчитает массу), но не соединит unload c plan, если в плане неподходит дата. А нужно, чтобы он не соединял incom с unload (и соответственно не считал массу), если в плане не подходит дата.
...
Рейтинг: 0 / 0
Джойны
    #40103955
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда надо так
Код: sql
1.
2.
3.
4.
5.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN unload u ON u.incom_id = i.id AND p.plan_date <= :a_date
LEFT JOIN plan p ON p.id = u.plan_id 
GROUP BY i.id


Но куда деть LEFT JOIN plan p?

Код: sql
1.
2.
3.
4.
5.
6.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN unload u ON 
    LEFT JOIN plan p ON p.id = u.plan_id 
    u.incom_id = i.id AND p.plan_date <= :a_date
GROUP BY i.id


?
...
Рейтинг: 0 / 0
Джойны
    #40103957
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я ничего не понимаю из твоего объяснения. Предлагаю показать на примере - выложи CREATE TABLE для таблиц, INSERT INTO с примером данных, значение параметра-даты, и требуемый результат для именно этих данных.

svnvlad
нужно, чтобы он не соединял incom с unload (и соответственно не считал массу), если в плане не подходит дата.

Часом, не вот так ли?
Код: sql
1.
2.
3.
4.
5.
6.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN (            unload u 
            INNER JOIN plan p ON p.id = u.plan_id AND p.plan_date <= :a_date 
          ) ON u.incom_id = i.id 
GROUP BY i.id
...
Рейтинг: 0 / 0
Джойны
    #40103960
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
Я ничего не понимаю из твоего объяснения. Предлагаю показать на примере - выложи CREATE TABLE для таблиц, INSERT INTO с примером данных, значение параметра-даты, и требуемый результат для именно этих данных.

svnvlad
нужно, чтобы он не соединял incom с unload (и соответственно не считал массу), если в плане не подходит дата.

Часом, не вот так ли?
Код: sql
1.
2.
3.
4.
5.
6.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN (            unload u 
            INNER JOIN plan p ON p.id = u.plan_id AND p.plan_date <= :a_date 
          ) ON u.incom_id = i.id 
GROUP BY i.id


Да, что-то такое.
Вот данные и пример с желаемым результатом:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
CREATE TABLE `incom` (
  `id` INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY USING BTREE (`id`),
) ENGINE=InnoDB
AUTO_INCREMENT=1 AVG_ROW_LENGTH=16384 ROW_FORMAT=DYNAMIC CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;

CREATE TABLE `plan` (
  `id` INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `plan_date` DATETIME NOT NULL,
  PRIMARY KEY USING BTREE (`id`),
) ENGINE=InnoDB
AUTO_INCREMENT=1 ROW_FORMAT=DYNAMIC CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;

CREATE TABLE `unload` (
  `id` INTEGER(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `plan_id` INTEGER(11) UNSIGNED NOT NULL, 
  `incom_id` INTEGER(11) UNSIGNED NOT NULL,
  `weight` DECIMAL(15,4) DEFAULT NULL,
  PRIMARY KEY USING BTREE (`id`),
  KEY `plan_id` USING BTREE (`plan_id`),  &#8203;
  KEY`incom_id` USING BTREE (`incom_id`),
 &#8203;CONSTRAINT `unload_fk1` FOREIGN KEY (`plan_id`) REFERENCES `plan` (`id`),
 &#8203;CONSTRAINT `unload_fk2` FOREIGN KEY (`incom_id`) REFERENCES `incom` (`id`),
) ENGINE=InnoDB
AUTO_INCREMENT=1 AVG_ROW_LENGTH=138 ROW_FORMAT=DYNAMIC CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'
;


INSERT INTO incom VALUES (1);

INSERT INTO plan VALUES (1, '2021-10-01');
INSERT INTO plan VALUES (2, '2021-10-02');
INSERT INTO plan VALUES (3, '2021-10-03');
INSERT INTO plan VALUES (4, '2021-10-04');
INSERT INTO plan VALUES (5, '2021-10-05');
INSERT INTO plan VALUES (6, '2021-10-06');
INSERT INTO plan VALUES (7, '2021-10-07');
INSERT INTO plan VALUES (8, '2021-10-08');
INSERT INTO plan VALUES (9, '2021-10-09');

INSERT INTO unload VALUES(1, 1, 1, 100);
INSERT INTO unload VALUES(2, 2, 1, 100);
INSERT INTO unload VALUES(3, 3, 1, 100);
INSERT INTO unload VALUES(4, 4, 1, 100);
INSERT INTO unload VALUES(5, 5, 1, 100);
INSERT INTO unload VALUES(6, 6, 1, 100);
INSERT INTO unload VALUES(7, 7, 1, 100);
INSERT INTO unload VALUES(8, 8, 1, 100);
INSERT INTO unload VALUES(9, 9, 1, 100);



Значение параметра a_date = '2021-10-04'.
Желаемый результат: i.id = 1, SUM(u.weight) = 400
...
Рейтинг: 0 / 0
Джойны
    #40103961
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Схема БД.
Смысл в том, чтобы показать, сколько было разгружено на такую-то дату.
...
Рейтинг: 0 / 0
Джойны
    #40103964
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, последний вариант сработал
Код: sql
1.
2.
3.
4.
5.
6.
SELECT i.id, SUM(u.weight)
FROM incom i
LEFT JOIN (unload u 
            INNER JOIN plan p ON p.id = u.plan_id AND p.plan_date <= :a_date 
          ) ON u.incom_id = i.id 
GROUP BY i.id
...
Рейтинг: 0 / 0
Джойны
    #40103977
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Джойны
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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