Как устранить неоднозначную ошибку имени столбца SQL - PullRequest
0 голосов
/ 24 октября 2018

Я использую следующий запрос и получаю сообщение об ошибке: «неоднозначное имя столбца« область ». Я провел некоторое чтение и обнаружил, что причиной ошибки является наличие его в CTE, а не группирование по / упорядочению по.в моем случае, кажется. Конечный результат этого запроса должен выглядеть примерно так, как показано ниже. Любые идеи относительно того, где мне нужно добавить / вычесть упоминание области?

Чтобы дать некоторый контекст,причина для некоторых элементов состоит в том, чтобы результирующий набор содержал заранее определенный список размерного сечения, даже если нет данных. Для некоторых областей нет данных. Население 650 не учитывает некоторые отрасли. Кроме того, существуетв xyzfirms201701 - 29 столбцов. Area, sizeclassep, owner и naicscode - это только некоторые из полей, содержащихся в нем.

Данные являются конфиденциальными и, к сожалению, данные не могут быть предоставлены

;with sizeclasseptable as 
(
select area,ownership,sizeclassep from (
select '01' as sizeclassep, '50' as ownership, area='000003'
union select '02' as sizeclassep, '50' as ownership, area='000003'
union select '03' as sizeclassep, '50' as ownership, area='000003'
union select '04' as sizeclassep, '50' as ownership, area='000003'
union select '05' as sizeclassep, '50' as ownership, area='000003'
union select '06' as sizeclassep, '50' as ownership, area='000003'
union select '07' as sizeclassep, '50' as ownership, area='000003'
union select '08' as sizeclassep, '50' as ownership, area='000003'
union select '09' as sizeclassep, '50' as ownership, area='000003') t0
cross join ( select distinct area from xyzfirms201701 ) t1
)

SELECT
'000003' AS area,
t2.[SizeClassep],
COUNT(*) AS [Number of Worksites],
SUM(t2.Employment) AS [Employment In Size Class]
 from sizeclasseptable
 inner join xyzfirms201701 t2 
on t2.area=sizeclasseptable.area 
and t2.ownership=sizeclasseptable.ownership
and t2.sizeclassep = sizeclasseptable.sizeclassep
GROUP BY
t2.area, t2.SizeClassep
ORDER BY
t2.area, t2.SizeClassep


area    SizeClassep Number of Worksites Employment In Size Class
000003  01  10866   13138
000003  02  1275    8322
000003  03  831 11192
000003  04  492 14694
000003  05  116 7783
000003  06  61  8876
000003  07  8   2809
000003  08  11  7909
000003  09  3   5322

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

У вас в cte такое же имя столбца, как и у xyzfirms201701.Вы должны переименовать его в любой из таблиц, чтобы этот запрос работал.Кроме того, вы можете просто создать псевдоним столбца, как показано ниже.Однако перекрестное объединение здесь не имеет смысла, когда вам не нужны никакие столбцы из этой таблицы.Он просто создает повторяющиеся записи.

Следующее должно работать.Обратите внимание на псевдоним a1 для столбца области.

;with sizeclasseptable as 
(
select area,ownership,sizeclassep from (
select '01' as sizeclassep, '50' as ownership, area='000003'
union select '02' as sizeclassep, '50' as ownership, area='000003'
union select '03' as sizeclassep, '50' as ownership, area='000003'
union select '04' as sizeclassep, '50' as ownership, area='000003'
union select '05' as sizeclassep, '50' as ownership, area='000003'
union select '06' as sizeclassep, '50' as ownership, area='000003'
union select '07' as sizeclassep, '50' as ownership, area='000003'
union select '08' as sizeclassep, '50' as ownership, area='000003'
union select '09' as sizeclassep, '50' as ownership, area='000003') t0
cross join ( select distinct area a1 from xyzfirms201701 ) t1
)

SELECT
'000003' AS area,
t2.[SizeClassep],
COUNT(*) AS [Number of Worksites],
SUM(t2.Employment) AS [Employment In Size Class]
 from sizeclasseptable
 inner join xyzfirms201701 t2 
on t2.area=sizeclasseptable.area 
and t2.ownership=sizeclasseptable.ownership
and t2.sizeclassep = sizeclasseptable.sizeclassep
GROUP BY
t2.area, t2.SizeClassep
ORDER BY
t2.area, t2.SizeClassep
0 голосов
/ 24 октября 2018

У вас есть [область] в объединении area='000003', и у вас снова есть это в select distinct area from xyzfirms201701.Какой из них вы на самом деле хотите использовать в качестве «области»?Учитывая, что вы хотите получить только '000003' в конечном результате, используйте t0.area (см. Вторую строку ниже).

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

В настоящее время вы группируете по t2.area, но не включаете его в предложение select.Либо пропустите его из группировки, либо включите в предложение select.Обратите внимание, поскольку [область] является частью объединения, оно может быть любым значением, которое вы указали в CTE, поэтому я предлагаю вам использовать sizeclasseptable.area

;with sizeclasseptable as (
    select t0.area,ownership,sizeclassep 
    from (
                  select '01' as sizeclassep, '50' as ownership, area='000003'
        union all select '02' as sizeclassep, '50' as ownership, area='000003'
        union all select '03' as sizeclassep, '50' as ownership, area='000003'
        union all select '04' as sizeclassep, '50' as ownership, area='000003'
        union all select '05' as sizeclassep, '50' as ownership, area='000003'
        union all select '06' as sizeclassep, '50' as ownership, area='000003'
        union all select '07' as sizeclassep, '50' as ownership, area='000003'
        union all select '08' as sizeclassep, '50' as ownership, area='000003'
        union all select '09' as sizeclassep, '50' as ownership, area='000003'
        ) t0
    /* cross join ( select distinct area from xyzfirms201701 ) t1 */
    )

SELECT
    sizeclasseptable.area  AS [area]
  , t2.SizeClassep
  , COUNT(*)               AS [Number of Worksites]
  , SUM(t2.Employment)     AS [Employment In Size Class]
FROM sizeclasseptable
LEFT JOIN xyzfirms201701 t2 ON t2.area = sizeclasseptable.area
    AND t2.ownership = sizeclasseptable.ownership
    AND t2.sizeclassep = sizeclasseptable.sizeclassep
GROUP BY
    sizeclasseptable.area
  , t2.SizeClassep
ORDER BY
    sizeclasseptable.area
  , t2.SizeClassep

edit

Альтернативный подход:

DECLARE @ownership varchar(20) = '50'
DECLARE @area varchare(20) = '000003'

WITH sizeclasseptable
AS (
    SELECT
        sizeclassep
    FROM (
                  select '01' as sizeclassep
        union all select '02' as sizeclassep
        union all select '03' as sizeclassep
        union all select '04' as sizeclassep
        union all select '05' as sizeclassep
        union all select '06' as sizeclassep
        union all select '07' as sizeclassep
        union all select '08' as sizeclassep
        union all select '09' as sizeclassep
    ) t0
)

SELECT
    t2.area
  , t2.SizeClassep
  , COUNT(*)           AS [Number of Worksites]
  , SUM(t2.Employment) AS [Employment In Size Class]
FROM sizeclasseptable
LEFT JOIN xyzfirms201701 t2 ON t2.area = @area
AND t2.ownership = @ownership
AND t2.sizeclassep = sizeclasseptable.sizeclassep
GROUP BY
    t2.area
  , t2.SizeClassep
ORDER BY
    t2.area
  , t2.SizeClassep

edit 2

Возможно, метод сокращения количества итераций запроса будет заключаться в расширении группировки на все3 из столбцов, используемых для выбора этих данных, а также расширение способа определения предложения where.Существует также другой метод получения строк SizeClassep с помощью values

SELECT
    t2.area
  , t2.SizeClassep
  , t2.ownership
  , COUNT(*)           AS [Number of Worksites]
  , SUM(t2.Employment) AS [Employment In Size Class]
FROM (
    SELECT
        sizeclassep
    FROM (
    VALUES ('01'), ('01'), ('03'), ('04'), ('05'), ('06'), ('07'), ('08'), ('09')
    ) t0 (sizeclassep)
) sizeclasseptable
LEFT JOIN xyzfirms201701 t2 ON t2.sizeclassep = sizeclasseptable.sizeclassep
AND t2.area IN ('0003','0004','0005','0006')  /* ALTER THE LIST TO SUIT YOUR NEEDS */
AND t2.ownership IN ('50','60','70')          /* ALTER THE LIST TO SUIT YOUR NEEDS */
AND 
GROUP BY
    t2.area
  , t2.SizeClassep
  , t2.ownership
ORDER BY
    t2.area
  , t2.SizeClassep
  , t2.ownership
...