MySQL включить и исключить данные из дочерней таблицы - PullRequest
1 голос
/ 09 апреля 2020

У меня есть несколько таблиц в моей базе данных MySQL, я застрял на одном запросе, пожалуйста, помогите.

Таблицы: projects categories project_categories client_categories

В projects table сохраняются сведения о проекте

В categories table сохраняются все категории

В project_categories сохраняются все категории, связанные с этим проектом

В client_categories выбранные клиентом категории проектов сохраняются (blacklisted или whitelisted)

Теперь мой сценарий состоит в том, что я хочу найти все проекты, имеющие выбранные клиентом категории со всеми категориями из белого списка, но без какой-либо категории из черного списка.

Я объясню это снова в табличной форме

Таблица проектов

+------------+--------------+
| project_id | project_name |
+------------+--------------+
| 1          | Proj_1       |
| 2          | Proj_2       |
| 3          | Proj_3       |
+------------+--------------+

Категории Таблица

+-------------+---------------+
| category_id | category_name |
+-------------+---------------+
| 1           | Cat_1         |
| 2           | Cat_2         |
| 3           | Cat_3         |
+-------------+---------------+

Таблица категорий проектов Таблица

+------------+-------------+
| project_id | category_id |
+------------+-------------+
| 1          | 1           |
| 1          | 2           |
| 1          | 3           |
| 2          | 1           |
| 2          | 3           |
| 3          | 3           |
+------------+-------------+

Таблица категорий клиентов

+-----------+-------------+--------+
| client_id | category_id | status |
+-----------+-------------+--------+
| 1         | 1           | white  |
| 1         | 2           | black  |
+-----------+-------------+--------+

Итак это моя структура и фиктивные данные. Теперь для этих данных у клиента есть белый список категории_1 и черный список категории_2, что означает, что он не должен видеть проект с категорией_2 и должен видеть только те проекты, которые имеют категорию_1

. Для этих данных

Project_1 - > не должен быть видимым (содержит category_id 2 , также содержит category_id 1 , но имеет меньший приоритет)

Project_2 -> должен быть видимым (содержит category_id 1 )

Project_3 -> не должен быть видимым (не содержит category_id 1 )

У меня написан этот запрос, он отлично работает, если я хочу только проекты из белого списка

SELECT projects.* FROM projects
INNER JOIN project_categories ON project_categories.project_id = projects.id
WHERE project_categories.category_id IN 
   (SELECT category_id FROM client_categories WHERE status='white')

Я немного изменил запрос для исключения категорий из черного списка, но не работает

SELECT projects.* FROM projects
INNER JOIN project_categories ON project_categories.project_id = projects.id
WHERE project_categories.category_id IN 
   (SELECT category_id FROM client_categories WHERE status='white')
AND project_categories.category_id NOT IN 
   (SELECT category_id FROM client_categories WHERE status='black')

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

здесь в основном нам потребовались те проекты, которые не имеют статус «черный», поэтому здесь я выбираю проекты со статусом черный, а затем исключаю их из полного списка проектов

select * from projects p where project_id not in (
    select p.project_id 
    from client_categories cc 
    join project_categories pc on cc.category_id = pc.category_id and cc.status  like 'b%'  
    join projects p on p.project_id = pc.project_id where cc.status like 'b%'
); 

надеюсь, это поможет

0 голосов
/ 10 апреля 2020

@ SyedKhan Я думаю, что этот запрос даст вам то, что вы ищете (если я правильно понимаю ваш желаемый результат). Этот запрос возвращает только project_2, потому что project_1 имеет категорию, которая находится в черном списке, а не project_3, потому что у него нет категории в белом списке:

SELECT `pr`.*
FROM `projects` AS `pr`
JOIN (
    SELECT `p`.*,
        GROUP_CONCAT(`cc`.`status`) AS `statuses`
    FROM `projects` AS `p`
    JOIN `project_categories` AS `pc` ON `pc`.`project_id` = 
    `p`.`project_id`
    JOIN `categories` AS `c` ON `c`.`category_id` = `pc`.`category_id`
    JOIN `customer_categories` AS `cc` ON `cc`.`category_id` = 
    `c`.`category_id`
    GROUP BY `p`.`project_id`
) AS `der` ON `der`.`project_id` = `pr`.`project_id`
    AND FIND_IN_SET('black', `der`.`statuses`) = 0
;

Вот пример в БД скрипка.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...