SQL WHEREing в другой таблице COUNT - PullRequest
0 голосов
/ 17 января 2010

Итак, я хочу применить условие WHERE к полю, назначенному предложением COUNT () AS. Мой запрос в настоящее время выглядит так:

SELECT new_tags.tag_id
       , new_tags.tag_name
       , new_tags.tag_description
       , COUNT(DISTINCT new_tags_entries.entry_id) AS entry_count 
FROM (new_tags) 
JOIN new_tags_entries ON new_tags_entries.tag_id = new_tags.tag_id 
WHERE `new_tags`.`tag_name` LIKE '%w' 
AND `entry_count` < '1' 
GROUP BY new_tags.tag_id ORDER BY tag_name ASC

Неудачный бит - это entry_count в предложении WHERE - он не знает, что такое столбец entry_count. Мой стол выглядит так:

new_tags {
    tag_id INT
    tag_name VARCHAR
}

new_tags_entries {
    tag_id INT
    entry_id INT
}

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

Имеет смысл?

Заранее спасибо.

Ответы [ 4 ]

2 голосов
/ 17 января 2010

Для фильтрации по агрегированным значениям используется предложение HAVING ...

SELECT  
   new_tags.tag_id, new_tags.tag_name,  
   new_tags.tag_description,  
   COUNT(DISTINCT new_tags_entries.entry_id) AS entry_count  
FROM (new_tags)  
JOIN new_tags_entries ON new_tags_entries.tag_id = new_tags.tag_id   
WHERE `new_tags`.`tag_name` LIKE '%w'   
GROUP BY new_tags.tag_id  
HAVING COUNT(DISTINCT new_tags_entries.entry_id)  < '1' 
ORDER BY tag_name ASC
1 голос
/ 17 января 2010

Хотя ответ APC будет синтаксически правильным, если проблема, которую вы пытаетесь решить, действительно такова: «Найдите мне все новые теги, у которых нет news_tags_entries», тогда запрос с INNER JOIN и GROUP BY и HAVING не даст правильный результат. Фактически, он всегда будет давать пустой набор.

Как указал Игнасио Васкес Абрахамс, LEFT JOIN будет работать. И вам даже не нужны GROUP BY / HAVING:

SELECT    news_tags.*
FROM      news_tags
LEFT JOIN news_tags_entries 
ON        news_tags.tag_id = news_tags_entries.tag_id
WHERE     news_tags_entries.tag_id IS NULL

(Конечно, вы все равно можете добавить GROUP BY и HAVING, если вам интересно узнать, сколько существует записей, а не просто хотите найти news_tags с нулем news_tags_entries. Но LEFT JOIN от news_tags до news_tags_entries должен быть там, иначе вы потеряете теги news, у которых нет соответствующих элементов в news_tags_items)

Другой, более явный способ решить «достань мне все x, для которого нет y» - это коррелированное NOT EXISTS решение:

SELECT    news_tags.*
FROM      news_tags
WHERE NOT EXISTS (
          SELECT NULL
          FROM   news_tags_entries
          WHERE  news_tags_entries.tag_id = news_tags.tag_id
          )

Хотя это и симпатичное и явное решение, в MySQL его обычно избегают из-за довольно низкой производительности подзапроса

1 голос
/ 17 января 2010

Внутреннее соединение никогда не будет иметь счет меньше 1. Возможно, левое соединение и IS NULL помогут. Это, или вместо SUM().

0 голосов
/ 17 января 2010
SELECT 
   new_tags.tag_id, new_tags.tag_name, 
   new_tags.tag_description, 
   COUNT(DISTINCT new_tags_entries.entry_id) AS entry_count 
FROM (new_tags) 
LEFT JOIN new_tags_entries ON new_tags_entries.tag_id = new_tags.tag_id  
WHERE `new_tags`.`tag_name` LIKE '%w'  
GROUP BY new_tags.tag_id ORDER BY tag_name ASC
HAVING `entry_count` < '1'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...