Как выбрать данные из таблицы с несколькими точками в одном столбце на основе другой таблицы в SQLite

#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 Все должно быть в порядке. Вы можете получить дополнительные столбцы, используя a join или что-то еще. Это не кажется главным в вашем вопросе.

5. Кажется, он работает, протестировал его, и пока он возвращает то, что мне нужно, мне нужно проверить его подробнее, можете ли вы объяснить, что вы сделали?