Запрашиваем таблицу привязки «многие ко многим» - PullRequest
1 голос
/ 28 июня 2019

У меня есть таблица связей для отношений «многие ко многим» с полями -

  • idNote
  • idTag

Я хотел бы отфильтровать все теги, связанные с заметками, которые содержат указанное количество тегов.

Например, если я выберу теги 'Running', 'Form' и 'Times', я бы хотел увидеть все теги, связанные с заметками, имеющими эти 3 тега. .

Этот процесс будет использоваться пользователем на внешнем интерфейсе для уточнения результатов, которые он ищет, поэтому мне нужно иметь возможность генерировать этот SQL с кодом (node.js), так как фильтрация по тегам может происходить во многих случаях. раз.

У меня есть приведенный ниже код SQL, который может запрашивать два тега, но есть некоторые проблемы с ним:

  1. Это не кажется эффективным
  2. Это не может быть легко сгенерировано с помощью кода, если необходимо добавить еще один слой файловых файлов
SELECT DISTINCT idtag FROM table WHERE idnote IN (SELECT idnote FROM 
(SELECT * FROM table WHERE idnote IN (SELECT idnote FROM table WHERE idtag 
= 'Example')) as t1 where t1.idtag = 'SecondExample');

Я надеюсь получить несколько советов о том, как повысить эффективность этого кода, а также о том, как превратить оператор sql в нечто, легко генерируемое кодом.

Ответы [ 3 ]

1 голос
/ 28 июня 2019

Похоже на ловушку данных, декартово произведение https://en.wikipedia.org/wiki/Cartesian_product

Есть ли что-то, что может связать две таблицы? Как общая таблица между двумя, к которой мы можем присоединиться?Вместо N: N
таблица A будет чем-то общим с таблицей заметок (B) и таблицей тегов (C), мы можем иметь соединение таблицы A с таблицей B как 1: N, а таблицы A также объединение с C как 1: N

Тогда вы можете объединить два отдельных факта в общую таблицу

0 голосов
/ 28 июня 2019

Я использовал ваш пример 'Running','Form','Times' в качестве указанного набора тегов.

select distinct idTag from table 
where idNote in (select idNote from table where idTag in ('Running'))
and idNote in (select idNote from table where idTag in ('Form'))
and idNote in (select idNote from table where idTag in ('Times'))


0 голосов
/ 28 июня 2019

Попробуйте что-то вроде этого:

; with cteTagList as 
    (select 'Example' idtag
    union select 'SecondExample'
    --...
    union select 'LastExample'
    )
select t.idnote
from table t inner join cteTabList l on l.idtag = t.idtag
group by t.idnote
having count(*) = [NUMBER_OF_SEARCH_TAGS]

Где вы генерируете CTE (выражение общей таблицы), которое содержит все поисковые теги.Объедините его с таблицей отношений «многие ко многим» и выберите только те примечания, в которых число запросов равно числу поисковых тегов, введенных пользователем, отмеченных [NUMBER_OF_SEARCH_TAGS] в запросе

...