powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Необходимо выбрать все возможные пары из таблицы
18 сообщений из 18, страница 1 из 1
Необходимо выбрать все возможные пары из таблицы
    #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
Необходимо выбрать все возможные пары из таблицы
    #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
Необходимо выбрать все возможные пары из таблицы
    #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
Необходимо выбрать все возможные пары из таблицы
    #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
Необходимо выбрать все возможные пары из таблицы
    #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
Необходимо выбрать все возможные пары из таблицы
    #40001866
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a.m.bal
На WITH ругается
Если автор не сообщает версию сервера, считается, что у него актуальная версия. Однако, судя по сообщению, у Вас древняя пятёрка. Кстати, обрезка хвоста сообщения об ошибке - худшее, что можно сделать, сообщая о ней.
a.m.bal
Необходимо, пользуясь условием, что если a=x и b=x , то и a=b , привести таблицу к виду

Приплыли... это ещё более гадостная задача. И на Вашей версии она запросом не решается в принципе - только в формате хранимой процедуры.
...
Рейтинг: 0 / 0
Необходимо выбрать все возможные пары из таблицы
    #40001875
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a.m.bal
если a=x и b=x , то и a=b
А если a=x, b=x, b=y c=y, то a=c ?
...
Рейтинг: 0 / 0
Необходимо выбрать все возможные пары из таблицы
    #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
Необходимо выбрать все возможные пары из таблицы
    #40001946
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crutchmaster
но вроде работает
Да ни фига не работает. Поменяй в fiddle последнюю запись на ('c','b') .
...
Рейтинг: 0 / 0
Необходимо выбрать все возможные пары из таблицы
    #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
Необходимо выбрать все возможные пары из таблицы
    #40002032
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,

Поменял.
a_idb_idabbaxbxabxaxcbbc

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

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

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

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

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

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

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

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

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

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

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

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

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


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