powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Проверка пересечения двух множеств на лету
18 сообщений из 18, страница 1 из 1
Проверка пересечения двух множеств на лету
    #38620344
Cyrax_02
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется php-массив целых чисел. Назовём его $ARR.
Имеется таблица table с полем field. Поле field содержит строку вида "4,5,6,7,8,7,64,34434,44,6,8" - т.е. список целых чисел.

Задача : в запросе налету отобрать те поля table.field, список которых пересекается со списком ARR
Т.е. в идеале необходимо что-то вроде такого:
Код: php
1.
query = "SELECT table.field FROM table WHERE (INTERSECTED(table.field, ".implode(',' $ARR)."))"

Но функции INTERSECTED в mySQL нет

Другой вариант - в цикле получаем вот такое условие:
Код: php
1.
2.
3.
4.
5.
query = "SELECT table.field FROM table WHERE (FIND_IN_SET(table.field, ".$ARR[0].") OR
                                             (FIND_IN_SET(table.field, ".$ARR[1].") OR
                                             (FIND_IN_SET(table.field, ".$ARR[2].") OR
                                             (FIND_IN_SET(table.field, ".$ARR[3].") OR
                                             ...)"


Третий вариант:
На лету раскладываем список $ARR в отдельные значения (операция, обратная GROUP_CONCAT). В итоге на лету мы получаем таблицу, отражающую связь "М:М" и далее уже делаем элементарную выборку.
Только как этот вариант реализовать на лету ?

P.S. Требуется найти самый быстрый способ без использования хранимых процедур (функций). Т.е. все операции выполняем на лету.
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620399
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и чем тебе не нравится "другой" вариант?
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620405
bochkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
все это очень уродливо,медленно и не рационально
с таким подходом зачем нужен mysql?
в файл писать-читать быстрее будет
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620411
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 21.04.2014 14:21, Cyrax_02 wrote:

> Имеется php-массив целых чисел. Назовём его $ARR.
> Имеется таблица table с полем field. Поле field содержит строку вида
> "4,5,6,7,8,7,64,34434,44,6,8" - т.е. список целых чисел.

Мужчина, тебе надо почитать о 1-ой нормальной форме и в соответствии с
прочитанным модифицировать структуру твоей БД.

далее -- просто not in
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620413
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так хранить
Поле field содержит строку вида "4,5,6,7,8,7,64,34434,44,6,8"
тоже не рационально
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620458
Cyrax_02
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторвсе это очень уродливо,медленно и не рационально
с таким подходом зачем нужен mysql?
Реализация модели универсальной БД в одной из CMS не совсем эффективна.
Как следствие, приходится решать подобные задачи. Посему, вопрос остаётся в силе.

автори чем тебе не нравится "другой" вариант?
Нравится, только не исключаю и другие, более эффективные варианты
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620466
Cyrax_02
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вариант №3 реализовать слабо ?
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620482
bochkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не слабо, но лениво
и нужна таблица где количество записей больше или равно количеству элементов в массиве для эмуляции цикла
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620726
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cyrax_02На лету раскладываем список $ARR в отдельные значения (операция, обратная GROUP_CONCAT). В итоге на лету мы получаем таблицу, отражающую связь "М:М" и далее уже делаем элементарную выборку.
Только как этот вариант реализовать на лету ?



Ненадо на лету.
Надо стационарно.
Если ТУ структуру менять нельзя вообще, то можно сделать дополнительную таблицу, поддерживаемую триггерами на изменение той таблицы, где это уже лежит.
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620766
Cyrax_02
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если готовить мало сложных запросов (по принципу "все данные в одном запросе"), а не много простых, то имеет место такая ситуация (кто работал с CMS, тот знает):
Время генерации страницы CMS'кой в десятки раз превышает время выполнения этих самых (собственноручно составленных) сложных запросов. А у меня как раз мания по составлению сложных запросов.

Посему на данный нет никакой необходимости в дополнительных оптимизирующих таблицах (с нормализованными данными).

P.S. Особенно, если результаты выполнения запросов кэшировать в оперативной памяти (в пределах одной загрузки страницы), чтобы одни и те же запросы не выполнять несколько раз в процессе генерации страницы. А это я тоже реализовал.

Вот и получилось, что даже с такими ненормализованными данными мои запросы выполняются в десятки раз быстрее, чем CMS генерирует страницу.
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38620852
Cyrax_02
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Блин. А ведь придётся такую задачу решать.
Есть таблица table1 с полем field1 и таблица table2 с полем field2. Оба поля представляют собой строковые списки (например, "1,34,5,78,9").
Необходимо для каждой строки таблицы table1 получить количество строк из таблицы table2, для которых множества пересекаются.
Т.е. запрос может быть таким:

Код: sql
1.
2.
3.
SELECT table1.id1, COUNT(table2.field2)
FROM table1 LEFT JOIN table2 ON (INTERSECTED(table1.field1, table2.field2))
GROUP BY table1.id1


Здесь хранимую функцию INTERSECTED можно и написать. Не вопрос.
Только вот проблема в том, что эта функция должна будет отработать очень много раз: число вызовов = произведению количеств строк в таблицах. Т.е. если в каждой из таблиц будет по 1000 записей, функция должна будет отработать 1000 000 раз. Здесь и без тестов можно сказать, что время выполнения такого запроса будет неприемлемым.

Возможны 2 варианта:
1. Формировать дополнительные оптимизирующие таблицы, куда будут копироваться те же данные, но в нормализованном виде
2. Напрячь мозг и составить вот такой чудо-запрос:
авторНа лету раскладываем список $ARR в отдельные значения (операция, обратная GROUP_CONCAT). В итоге на лету мы получаем таблицу, отражающую связь "М:М" и далее уже делаем элементарную выборку.
Только как этот вариант реализовать на лету ?
Первый вариант слишком геморройный по трудоёмкости.
По второму варианту: для получения таблицы с достаточным числом записей можно взять за основу системную таблицу information_schema или mysql и на лету состряпать из них требуемое декартово произведение.

Кто поможет ?
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38621725
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Модератор: Флуд и оффтоп зачищен.
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38621793
bochkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
было дело, парсили массивы в строках
таблица test.testtable содержит одну строку и одну колонку с числами через запятую
осталось определить таблицу [table_with_many_rows],
которая содержит количество записей >= количества элементов в поле field,
с любыми данными, даже из соседней базы, она нам нужна для организации цикла в запросе,
если строк не хватит то массив не распарсится
[php_array_joined_by_coma] это подстановка массива php
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT id FROM
(SELECT @index:=INSTR(@a,',') as coma_index,
@id:=SUBSTRING_INDEX(@a, ',', 1)  as id,
@a:=SUBSTRING(@a,IF(@index,@index+1,0)),
@a:=CONCAT_WS(IF(LENGTH(@a)>0,',',''),@a) as array
FROM 
(SELECT @a:=testtable.field FROM test.testtable LIMIT 1) as init,
[table_with_many_rows]
WHERE LENGTH(@a)>0) as arr 
WHERE arr.id IN([php_array_joined_by_coma])
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38621826
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bochkovбыло дело, парсили массивы в строках
таблица test.testtable содержит одну строку и одну колонку с числами через запятую
осталось определить таблицу [table_with_many_rows],
которая содержит количество записей >= количества элементов в поле field,
с любыми данными, даже из соседней базы, она нам нужна для организации цикла в запросе,
если строк не хватит то массив не распарсится
[php_array_joined_by_coma] это подстановка массива php
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT id FROM
(SELECT @index:=INSTR(@a,',') as coma_index,
@id:=SUBSTRING_INDEX(@a, ',', 1)  as id,
@a:=SUBSTRING(@a,IF(@index,@index+1,0)),
@a:=CONCAT_WS(IF(LENGTH(@a)>0,',',''),@a) as array
FROM 
(SELECT @a:=testtable.field FROM test.testtable LIMIT 1) as init,
[table_with_many_rows]
WHERE LENGTH(@a)>0) as arr 
WHERE arr.id IN([php_array_joined_by_coma])



Вот еше одно решение на переменных 8434456 .

разницу в подходах мы уже несколько раз обсуждали :-)
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38622165
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftМодератор: Флуд и оффтоп зачищен.

Это не флуд и оффтоп, это — живое человеческое общение.
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38623944
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вариант пересечение двух множеств в виде таблицы
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SET @a='a,d,ff,g,t,h';
SET @php='a2,d,ff,rg,t';
SELECT
  id
FROM (SELECT
    @index := INSTR(@a, ',') ,
    @id := SUBSTRING_INDEX(@a, ',', 1) AS id,
    @a := SUBSTRING(@a, IF(@index, @index + 1, 0))
  FROM (SELECT
           @a) AS init,
       [table_with_many_rows]
  WHERE LENGTH(@a) > 0) AS arr
WHERE FIND_IN_SET(id,@php)>0;


немного оптимизированный 15917229 для работы в хранимке
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38623995
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну и как решение 15926825
...
Рейтинг: 0 / 0
Проверка пересечения двух множеств на лету
    #38624458
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадя
Код: sql
1.
2.
3.
FROM (SELECT
           @a) AS init,
       [table_with_many_rows]

Можно чуть проще:
Код: sql
1.
FROM (SELECT @a FROM [table_with_many_rows]) AS init
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Проверка пересечения двух множеств на лету
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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