Что мне нужно в моем запросе, возможно, НЕ СУЩЕСТВУЕТ или НЕ ВХОДИТ?

У меня есть таблица с названием review:

review_id   cat_id   public_or_private
1           1              0
11          2              2
12          3              1
13          4              2
14          5              2

И таблица с названием category:

cat_id   user_id  
1        10298            
2        10299
3        10300
4        10299
5        10298

Мое заявление:

$sql2 = "SELECT * 
        FROM review 
            INNER JOIN category ON review.cat_id = category.cat_id 
        WHERE review.public_or_private = 2"; 

Это даст мне результат:

review_id   cat_id   public_or_private   cat_id   user_id              
    11          2              2           2        10299
    13          4              2           4        10299
    14          5              2           5        10298

contacts таблица:

user_id    contact_id
10299       10298
10299       10300
10300       10298
10300       10301

Как я могу отточить это дальше? : Мне нужны результаты, только если user_id не находится в столбце contact_id таблицы contacts.

Итак, с точки зрения пользователя 10300 результат должен быть:

review_id   cat_id   public_or_private   cat_id   user_id              
    11          2              2           2        10299
    13          4              2           4        10299

Я считаю, что мне следует использовать NOT EXISTS или NOT IN, но не знаю, как это сказать.


person CHarris    schedule 20.06.2019    source источник
comment
Я нахожу использование user_id и contact_id очень запутанным. Что они собой представляют? Что все это означает и что на самом деле делает запрос, который вы хотите?   -  person KIKO Software    schedule 20.06.2019
comment
У каждого пользователя приложения есть user_id, который подключается к базе данных через php и выполняет разные операции. Таблица contacts в столбце contact_id содержит контакты 10300 или того, кто user_id вошел в систему. Надеюсь, это немного проясняет ситуацию ...   -  person CHarris    schedule 20.06.2019
comment
Итак, вам нужен запрос, который для любого пользователя, у которого еще нет контактов, возвращал отзывы с public_or_private = 2, а также возвращал пользователей, написавших эти отзывы. Это только для одного бесконтактного пользователя? Или несколько?   -  person KIKO Software    schedule 20.06.2019
comment
Пожалуйста, внимательно изучите, прежде чем размещать вопрос. Часто ответы уже есть.   -  person mickmackusa    schedule 20.06.2019
comment
@KIKOSoftware Да, правильно. Это будет для любого user_id, который входит в систему. Я смотрю на ответ alx ниже, думаю, он, возможно, решил мою проблему. Tx.   -  person CHarris    schedule 20.06.2019


Ответы (1)


Думаю, это то, что вам нужно:

SELECT * 
        FROM review 
            INNER JOIN category ON review.cat_id = category.cat_id
            LEFT JOIN contacts ON contacts.user_id = category.user_id
        WHERE review.public_or_private = 2
        AND contacts.contact_id IS NULL

И вот пример, подтверждающий это утверждение: http://www.sqlfiddle.com/#!9/7bfb62/3

Это тоже работает:

SELECT * 
        FROM review 
            INNER JOIN category ON review.cat_id = category.cat_id
        WHERE review.public_or_private = 2
        AND NOT EXISTS(
            SELECT *
            FROM contacts
            WHERE contacts.user_id = category.user_id
       );

И вот обновленная скрипка: http://www.sqlfiddle.com/#!9/7bfb62/5

person alx    schedule 20.06.2019
comment
К сожалению, это повторяющийся вопрос. - person mickmackusa; 20.06.2019
comment
@mickmackusa Почти все вопросы в некотором роде дублируются. Вы говорите, что вы решили закрыть этот вопрос. - person KIKO Software; 20.06.2019
comment
Правильно, почти все вопросы дублируются. - person mickmackusa; 20.06.2019
comment
Да, и два других вопроса по какой-то причине не помечены как повторяющиеся. - person alx; 20.06.2019
comment
@mickmackusa Пометка вопросов как дубликатов делается для улучшения качества содержимого Stack Overflow, но какие вопросы фактически закрыты, как это, довольно произвольно. Это просто нехорошо, когда вы потратили время на подготовку ответа, а кто-то просто лишает возможности дать его. Это заставляет вас отвечать быстро, но не слишком тщательно, а это противоположно первоначальной цели маркировки дубликатов. (кстати, не твоя вина) - person KIKO Software; 20.06.2019
comment
Я бы сказал, есть хорошие и плохие дубликаты. Хорошие - когда один и тот же вопрос задается по-разному, что добавляет разные варианты использования, контекст и ключевые слова для поиска. Плохие - это просто плохие вопросы: слишком мало или совсем не гуглить, прежде чем задавать вопросы. Этот плохой, кстати. - person alx; 20.06.2019
comment
@alx Отлично, спасибо. Ваш запрос действительно дал мне тот, который я НЕ искал :) но я изменил его - я использую AND NOT EXISTS на AND NOT EXISTS(SELECT * FROM contacts WHERE contacts.contact_id = category.user_id);, и теперь он дает правильный результат. - person CHarris; 20.06.2019
comment
@mickmackusa На самом деле я потратил несколько часов, пытаясь решить проблему сам, прежде чем писать. И я не публикую легкомысленно, потому что вопрос иногда занимает больше времени, чем исследование, которое вы проводили заранее. - person CHarris; 20.06.2019
comment
Это тоже верный момент: иногда вы не знаете достаточно, чтобы правильно задать вопрос. (Я слишком часто оказываюсь в таком положении, TBH.) Вероятно, это потому, что, как говорится, правильный вопрос уже содержит 50% ответа. А ТАК - это один огромный котел людей и знаний, без разнообразия по уровню знаний. - person alx; 20.06.2019