Повторное использование псевдонима в соединении - PullRequest
0 голосов
/ 16 сентября 2011

Я пытаюсь добавить столбец, созданный с помощью COUNT(*) и GROUP BY, к исходному выбору, который был посчитан. Однако выбор довольно сложный (гораздо больше, чем строка WHERE ..., которую я включил в мой пример), поэтому я бы не стал дублировать код.

SQL Server не одобряет использование псевдонима t1 внутри левого оператора соединения. Есть предложения?


select t1.school, t1.grade,t1.individual,t2.cnt as 'class size' from (
        select * from students
        where (students.age < 16 and students.ACT_score is not null)
) as t1
left join (
    select distinct school, grade, count(*) as 'cnt' from t1
    group by school, grade
) as t2
on t1.school = t2.school and t1.grade = t2.grade

Ответы [ 3 ]

3 голосов
/ 16 сентября 2011

Может быть проще поддерживать, если вы используете COUNT (*) с предложением OVER следующим образом:

with cntAppended as (
  select
    *,
    count(*) over (partition by school, grade)
  from students
)
  select
    school, 
    grade,
    individual,
    cnt as "class size"
from cntAppended
where (age < 16 and ACT_score is not null)

Не поддавайтесь искушению избегать использования WITH и помещать предложение WHERE в один запрос с помощью COUNT. Если вы это сделаете, вы будете считать только учеников в каждой школе и классе, которые младше 16 лет и имеют оценки ACT. Похоже, что вы хотите сосчитать всех студентов для столбца [размер класса], но видите в результатах только данные для определенных учеников.

Если и когда T-SQL поддерживает ключевое слово QUALIFY , подобные запросы могут быть еще проще:

select
  school, 
  grade,
  individual,
  count(*) over (partition by school, grade) as "class size"
from students
QUALIFY (age < 16 and ACT_score is not null)
3 голосов
/ 16 сентября 2011

Если это 2005 или новее, используйте CTE:

;WITH MyCTE AS
(
<Your complicate query here>
)
SELECT fields
FROM MyCTE
JOIN (subquery referencing MyCTE)
...
1 голос
/ 16 сентября 2011

Я переписал ваш запрос в более простой форме, CTE не требуется:

SELECT t1.school
    ,t1.grade
    ,t1.individual
    ,t2.cnt AS 'class size'
FROM students t1
LEFT JOIN (
    SELECT school
        ,grade
        ,count(*) AS 'cnt'
    FROM students 
    GROUP BY school, grade
) AS t2 ON t1.school = t2.school
        AND t1.grade = t2.grade
WHERE t1.age < 16
    AND t1.ACT_score IS NOT NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...