2014-01-02 2 views
0

Рассмотрите следующий подзапрос. Этот запрос извлекает все личные данные сотрудников, у которых есть более 1 'IDKleerkastPersoon'. Для этого вопроса я использую оператор COUNT() в моем HAVING. Эта подзадача возвращает все персональные идентификаторы для сотрудников.SQL subQuery с COUNT() в инструкции WHERE/HAVING

(SELECT  DISTINCT Persoon_1.Stamnr 
FROM   dbo.KleerkastPerPersoon AS KleerkastPerPersoon_1 INNER JOIN 
               dbo.Persoon AS Persoon_1 ON KleerkastPerPersoon_1.ID_Persoon = Persoon_1.ID_Persoon 
         GROUP BY Persoon_1.Stamnr, Persoon_1.ID_Afdeling, KleerkastPerPersoon.IDKleerkastPersoon, Persoon.Naam 
         HAVING  (Persoon_1.ID_Afdeling = 2) AND (COUNT(KleerkastPerPersoon.IDKleerkastPersoon) >= 2) 
         ORDER BY Persoon_1.Stamnr DESC) 

Теперь пользователь запросил дополнительную информацию, а затем только PersonalId сотрудников. Поэтому я написал над ним запрос (см. Ниже), который извлекает более глобальную информацию о сотруднике. Как и ожидалось, сервер sql отвергает этот метод.

SELECT  dbo.Persoon.Stamnr, dbo.Persoon.Naam, dbo.Persoon.Voornaam, dbo.Refter.RefterOmschrijving, dbo.Kleedkamer.KleedkamerOmschrijving, 
        dbo.Kleerkast.KleerkastOmschrijving 
FROM   dbo.KleerkastPerPersoon INNER JOIN 
        dbo.Persoon ON dbo.KleerkastPerPersoon.ID_Persoon = dbo.Persoon.ID_Persoon INNER JOIN 
        dbo.Kleerkast INNER JOIN 
        dbo.Kleedkamer ON dbo.Kleerkast.ID_Kleedkamer = dbo.Kleedkamer.ID_Kleedkamer INNER JOIN 
        dbo.Refter ON dbo.Kleedkamer.ID_Refter = dbo.Refter.ID_Refter ON dbo.KleerkastPerPersoon.ID_Kleerkast = dbo.Kleerkast.ID_Kleerkast 
WHERE  (dbo.Persoon.Stamnr IN <<<Result of my first subquery>>> 
        ) 

Сообщение об ошибке броска является:

An aggregate may not appear in the where clause unless it is in a subquery contained in a having clause or a select list, and the column being aggregated is an outer reference 

Так я переместил подзапрос к имеющей п:

<<<Query 2>>> 
HAVING  (dbo.Persoon.Stamnr IN 
         (SELECT  TOP (100) PERCENT Persoon_1.Stamnr 
         FROM   dbo.KleerkastPerPersoon AS KleerkastPerPersoon_1  INNER JOIN 
               dbo.Persoon AS Persoon_1 ON KleerkastPerPersoon_1.ID_Persoon = Persoon_1.ID_Persoon 
         GROUP BY Persoon_1.Stamnr, Persoon_1.ID_Afdeling 
         HAVING  (Persoon_1.ID_Afdeling = 2) AND (COUNT(KleerkastPerPersoon.IDKleerkastPersoon) >= 2) 
         ORDER BY Persoon_1.Stamnr DESC)) 

Но теперь запрос не возвращает никаких результатов. Хотя я должен видеть 98 разных записей. У любого из вас есть решение моей проблемы или моего обходного пути? Как я могу удалить необходимость в подзапросе, например.

ответ

2

Сохраните результат первого подзапроса в переменной таблицы, а затем используйте его в своем окончательном запросе. Также нет необходимости в предложении Order By в подзапросе, если вы не используете TOP.

+0

Красиво отмечены. Это «Заказ» на деле является излишним. Будет следить за вашими советами и создавать соблазнительные результаты для моего первого запроса. – User999999

1

Ну если я получаю то, что вы после этого что-то вроде

SELECT dbo.Persoon.Stamnr, dbo.Persoon.Naam, dbo.Persoon.Voornaam, dbo.Refter.RefterOmschrijving, dbo.Kleedkamer.KleedkamerOmschrijving, dbo.Kleerkast.KleerkastOmschrijving 
FROM dbo.KleerkastPerPersoon 
inner join (your original query) SomeSuitableAlias 
On SomeSuitableAlias.Stamnr = dbo.KleerkastPerPersoon.Stamnr 

должен делать эту работу.

+0

Вы можете сделать свой исходный запрос CTE, как предложено mhasan, и присоединиться к нему, если ничто другое не поможет читаемости. –

+0

Оба метода были чрезвычайно полезны, оба работали также. благодаря! – User999999

0

Я думаю, что совокупность в сообщении об ошибке относится к предложению GROUP BY и COUNT(KleerkastPerPersoon.IDKleerkastPersoon) в вашем первом запросе.

Когда вы используете этот выбор в качестве подзапроса, вы, по-видимому, ссылаетесь на что-то, что не является результатом предложения HAVING или оператора SELECT. Вы должны включать любые столбцы или агрегаты, которые вам нужны в результирующем наборе вашего подзапроса. Вы также должны оставить часть ORDER BY в подзапросе (если вы этого еще не сделали).

Я не вижу точно, что такое ссылка на нарушение, но я согласен с mhasan, что вы должны, по крайней мере, изначально разбить ваш запрос, используя некоторые временные таблицы, и когда вы его заработаете, в один запрос.