Гость
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Необходимо выбрать все возможные пары из таблицы / 18 сообщений из 18, страница 1 из 1
23.09.2020, 11:11
    #40001570
a.m.bal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
Прошу помощи.

Есть таблица с товарами и аналогами (ряду товаров прописан один и тот же аналог) вида:

product | product_analog
a | x
b | x
c | x


Необходимо вывести все возможные варианты "товар-аналог", то есть привести её к следующему виду:

product | product_analog
a | x
a | b
a | c
b | x
b | a
b | c
c | x
c | a
c | b
x | a
x | b
x | c
...
Рейтинг: 0 / 0
23.09.2020, 11:46
    #40001587
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
a.m.bal,

Для начала надо всё нормализовать, следовательно нужно две таблицы - product и product_analog (id_product, id_analog)
В таком случае запрос будет сделать легко и просто как-то так:
Код: sql
1.
2.
select a.product, b.product from product a, product_analog pa, product b 
   where a.id = pa.id_product and (pa.id_analog = b.id or (b.id = pa.id_analog and a.id = pa.id_analog))
...
Рейтинг: 0 / 0
23.09.2020, 12:22
    #40001611
a.m.bal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
crutchmaster,

Есть как раз две таблицы: product (id, наименование и т.д.) и product_analog (соответствие товара и аналога по id).

Правильно ли я понял, что в предложенном скрипте под a и b принимать таблицу product , а под pa - product_analog ?
Если правильно, то получаются некорректные, в виде:

product | product_analog
a | a
a | a
a | a
b | b
b | b
b | b
c | c
c | c
c | c
...
Рейтинг: 0 / 0
23.09.2020, 14:02
    #40001669
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
Код: sql
1.
2.
3.
4.
5.
6.
WITH cte AS ( SELECT product FROM goods
              UNION 
              SELECT product_analog FROM goods )
SELECT t1.product, t2.product product_analog
FROM cte t1
JOIN cte t2 ON t1.product != t2.product;


fiddle
...
Рейтинг: 0 / 0
23.09.2020, 15:08
    #40001713
a.m.bal
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
Akina,

На WITH ругается (Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ...)

Опишу задачу подробнее.

Есть таблица с соответствием "Товар-аналог" в виде:

product | product_analog
a | x
b | x

Необходимо, пользуясь условием, что если a=x и b=x , то и a=b , привести таблицу к виду:

product | product_analog
a | x
a | b
b | x
b | a
x | a
x | b
(другими словами, необходимо вывести все возможные сочетания аналогов)
...
Рейтинг: 0 / 0
23.09.2020, 19:24
    #40001866
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
a.m.bal
На WITH ругается
Если автор не сообщает версию сервера, считается, что у него актуальная версия. Однако, судя по сообщению, у Вас древняя пятёрка. Кстати, обрезка хвоста сообщения об ошибке - худшее, что можно сделать, сообщая о ней.
a.m.bal
Необходимо, пользуясь условием, что если a=x и b=x , то и a=b , привести таблицу к виду

Приплыли... это ещё более гадостная задача. И на Вашей версии она запросом не решается в принципе - только в формате хранимой процедуры.
...
Рейтинг: 0 / 0
23.09.2020, 19:48
    #40001875
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
a.m.bal
если a=x и b=x , то и a=b
А если a=x, b=x, b=y c=y, то a=c ?
...
Рейтинг: 0 / 0
24.09.2020, 05:28
    #40001933
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
a.m.bal,

Да, надо было 4 связи.
Код: sql
1.
2.
3.
4.
select a.id a_id, b.id b_id from product a, product_analog pa, product b, product_analog pb
where pb.id_analog = pa.id_analog and a.id <> b.id and 
      (a.id = pa.id_product or (a.id = pa.id_analog and b.id = pa.id_product)) and 
      (b.id = pb.id_product or (b.id = pb.id_analog and a.id = pb.id_product)) 


https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=94452249357de8b626841f4956d097ff

Писал так - сделал 4 связи, а потом отсекал лишнее поэтапно. Логика происходящего целиком так в голову и не влезла, но вроде работает, да и запрос благой.

Код: sql
1.
a.id = pa.id_product or (a.id = pa.id_analog and b.id = pa.id_product


Тут прямая и обратная связи - продукт - аналог, аналог продукт.
Код: sql
1.
2.
      (a.id = pa.id_product or (a.id = pa.id_analog and b.id = pa.id_product)) and 
      (b.id = pb.id_product or (b.id = pb.id_analog and a.id = pb.id_product)) 


Первое условие обеспечивает a->x x->a
Второе условие обеспечивает a->x->b и b->x->a, если я ничего не путаю.
...
Рейтинг: 0 / 0
24.09.2020, 07:31
    #40001946
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
crutchmaster
но вроде работает
Да ни фига не работает. Поменяй в fiddle последнюю запись на ('c','b') .
...
Рейтинг: 0 / 0
24.09.2020, 07:43
    #40001949
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE PROCEDURE get_pairs ()
BEGIN
CREATE TABLE temp (p1 CHAR(1), p2 CHAR(1), UNIQUE (p1, p2)) ENGINE = Memory;
INSERT IGNORE INTO temp 
SELECT id_product, id_analog FROM product_analog
UNION ALL
SELECT id_analog, id_product FROM product_analog;
REPEAT
    INSERT IGNORE INTO temp
    SELECT t1.p1, t2.p2
    FROM temp t1
    JOIN temp t2 ON t1.p2 = t2.p1;
UNTIL !ROW_COUNT() END REPEAT;
SELECT p1 id_product, p2 id_analog FROM temp WHERE p1 != p2 ORDER BY 1,2;
DROP TABLE temp;
END



fiddle
...
Рейтинг: 0 / 0
24.09.2020, 11:31
    #40002032
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
Akina,

Поменял.
a_idb_idabbaxbxabxaxcbbc

Что не так?
с->b->x->a нету?
...
Рейтинг: 0 / 0
24.09.2020, 11:50
    #40002046
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
Akina,

Всё, понял. Еще раз убедился, что херня этот ваш sql. Почти любую задачу проще решить императивно.
...
Рейтинг: 0 / 0
24.09.2020, 13:26
    #40002116
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
crutchmaster
Еще раз убедился, что херня этот ваш sql.

А на старом дерьме за что не возьмись - всё херня. Или это "всё, что я не знаю - всё херня"?

Кстати, а как насчёт просто версию обновить до актуальной?

crutchmaster
Почти любую задачу проще решить императивно.

Вот будет у тебя массив данных в пару терабайт - тогда я и посмотрю, как ты его потащишь в клиента для императивного решения...
...
Рейтинг: 0 / 0
24.09.2020, 17:16
    #40002254
Gluck99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
crutchmaster
Всё, понял. Еще раз убедился, что херня этот ваш sql. Почти любую задачу проще решить императивно.
Надо освоить проектирование БД для начала и не пытаться из хрен пойми как связанных таблиц одним запросом сделать корректную выборку. Автор, вероятно, делает БД автомобильных запчастей с поиском аналогов по оригиналу и наоборот (т.е. в обе стороны). Я такое писал в точности, только лет 10 назад. Никаких "восьмых марий" тогда не было и все работало.
Что касается императивных подходов, то это смешно - например, запчастей и аналогов может быть десятки миллионов строк, а результат должен формироваться за 1 секунду. Впрочем, те, кто сидят на фронтэнде и гоняют "императивно" 10 несчастных записей по массивам на клиенте, вряд ли когда-нибудь это осознают.
...
Рейтинг: 0 / 0
25.09.2020, 10:20
    #40002435
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
Akina
А на старом дерьме за что не возьмись - всё херня. Или это "всё, что я не знаю - всё херня"?

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

Akina
Вот будет у тебя массив данных в пару терабайт

Вот когда будет, тогда и поговорим. А по факту, в подавляющем большинстве случаев, ничего такого нет и всё влазит в ram целиком несколько раз.
...
Рейтинг: 0 / 0
25.09.2020, 10:23
    #40002438
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
Gluck99
Что касается императивных подходов, то это смешно - например, запчастей и аналогов может быть десятки миллионов строк, а результат должен формироваться за 1 секунду.

Но он в любом случае не будет формироваться за 1 секунду на огромном массиве данных, в этом нет смысла хоть с sql хоть без. Такое считают заранее и складывают и на какой хер писать невменяемую sql портянку, если можно вытащить данные и написать понятный код.
...
Рейтинг: 0 / 0
25.09.2020, 12:11
    #40002479
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
crutchmaster
Твоё решение - императивное. Я пытался наваять как нужно и мог бы что-то там выпрыгнуть с рекурсивными запросами, но увидел цикл со вставкой и тупо опустились руки.
Вообще-то это - всего лишь реализация рекурсивного CTE программно на версии, которая не знает про CTE.

Не очень понимаю на самом деле, какой в данном случае вкладывается смысл в термин "императивный". Если это попытка провести параллель с процедурой на языке высокого уровня, который мусолит массив по одному элементу - то термин применён явно не по делу.

Цикл со вставкой - это именно то, что находится под капотом рекурсивного CTE - у любого сервера. С той лишь разницей, что в моём коде условие окончания формируется ограничением уникального индекса (тогда как на СУБД, которая не поддерживает UNION DISTINCT в рекурсивном CTE, с окончанием рекурсии придётся солидно потрахаться). Другой вопрос, что хранимая процедура выполняется режиме интерпретации, тогда как рекурсивный CTE использует оптимизированные процедуры с повторным использованием плана выполнения.

Что же до опускания рук - ну сочувствую, чо...
...
Рейтинг: 0 / 0
25.09.2020, 12:13
    #40002481
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Необходимо выбрать все возможные пары из таблицы
crutchmaster
на какой хер писать невменяемую sql портянку, если можно вытащить данные и написать понятный код.
Невменяемую портянку (которая кстати, отработает гораздо быстрее Вашего "понятного кода") приходится писать потому, что кто-то до сих пор работает на сервере десяти, если не больше, лет от роду.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Необходимо выбрать все возможные пары из таблицы / 18 сообщений из 18, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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