#sql #database #sqlite
Вопрос:
У меня есть таблица сообщений, у каждого сообщения есть теги, у каждого тега есть тема, например:
Post name: Anything
Post tag: 1, 2, 3
1: is the id of Male
2: is the id of United States
3: is the id of India
1
Тег относится к теме «пол», 2
теги » и 3
«относятся к теме «страна».
Таблицы здесь такие:
posts:
- id
- name
tags:
- id
- name
- topic_id
topics:
- id
- name
tags_posts:
- tag_id
- post_id
Теперь я хочу сделать такой фильтр, если пользователь выбрал в пользовательском интерфейсе «Мужчина» и «Соединенные Штаты», поэтому я должен выбрать все публикации с тегами «Мужчина» и «Соединенные Штаты».
SELECT * FROM posts where tag_relation = Male and tag_relation = United States
tag_relation here means JOIN to tags_posts table
Но если пользователь выбрал в пользовательском интерфейсе «Мужчина», «Соединенные Штаты» и «Индия», поэтому я должен выбрать все сообщения с тегами «Мужчина» и » (Соединенные Штаты или Индия)».
SELECT * FROM posts where tag_relation = Male and (tag_relation = United States or tag_relation = India)
tag_relation here means JOIN to tags_posts table
Как вы можете видеть, если теги принадлежат к одной и той же теме, где должно быть OR
, но если они принадлежат к разным темам, то где должно быть AND
.
Поэтому вопрос здесь в том, как я могу присоединиться к таблицам тем и проверить, являются ли выбранные теги одной и той же темой, и сгруппировать выбранные теги на основе темы, а затем выполнить поиск на основе этого.
Ответ №1:
Хммм. Вы можете подсчитать темы, соответствующие каждой публикации, а затем сравнить их с количеством тем в предоставленных тегах. Вот один из методов, который возвращает идентификаторы записей:
select tp.post_id
from tags t join
tags_posts tp
on tp.tag_id = t.id
where t.tag in ( . . . ) -- the list here
group by tp.post_id
having count(distinct t.topic_id) = (select count(distinct t2.topic_id)
from tags t
where t2.tag in ( . . . ) -- the list here
);
Вы можете присоединиться к posts
таблице, чтобы получить другие столбцы (или использовать exists
in
или что угодно).
Вы также можете сделать это с помощью оконных функций. Однако count(distinct)
это не поддерживается, поэтому вместо этого вы можете использовать метод dense_rank()
sum:
select tp.post_id
from (select t.*,
(-1
dense_rank() over (order by t.topic_id asc)
dense_rank() over (order by t.topic_id desc)
) as num_topics
from tags t
where t.tag in ( . . . )
) t join
tags_posts tp
on tp.tag_id = t.id
group by tp.post_id, t.num_topics
having count(distinct t.topic_id) = t.num_topics
Комментарии:
1. Вы выбираете теги, я хочу выбрать сообщения на основе тегов, также
in
предложение здесь не будет работать, потому что не все теги относятся к одной теме2. @MohamedHamdan . . . Это выбор сообщений, а не тегов.
3. сообщения находятся в таблице сообщений,
tags_posts
это только для связи, потому что связь между тегами и сообщениями много ко многим, поэтому сообщения находятся вposts
таблице, а связь между сообщениями и тегами-вtags_posts
таблице4. @MohamedHamdan . . .
post_id
Все должно быть в порядке. Вы можете получить дополнительные столбцы, используя ajoin
или что-то еще. Это не кажется главным в вашем вопросе.5. Кажется, он работает, протестировал его, и пока он возвращает то, что мне нужно, мне нужно проверить его подробнее, можете ли вы объяснить, что вы сделали?