如何解决歧义列名错误SQL

时间:2018-10-23 22:28:57

标签: join ssms common-table-expression ambiguous

我正在使用以下查询,并得到错误消息“歧义的列名'area'。我已进行了一些阅读,发现在CTE中而不是按分组/排序是错误的原因。就我而言,此查询的最终结果应如下所示。关于我需要在何处添加/减去区域的任何想法?

为了提供一些上下文,某些元素的原因是使结果集包含sizeclassep的预定列表,即使没有数据也是如此。对于某些区域,没有数据。 650名人口不允许某些行业。此外,xyzfirms201701中有29列。区域,sizeclassep,所有权和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 :(得分:1)

您在联合area='000003'中都具有[区域],在select distinct area from xyzfirms201701中又具有它。您实际上想将哪个用作“区域”?鉴于您似乎只希望在最终结果中使用'000003',然后使用t0.area(请参见下面的第二行)。

如果您在cte中使用交叉联接,我想您希望返回该联接的所有行,因此请使用左联接代替内部联接(?注意,我猜是这样)

您当前正在按t2.area分组,但不包括在select子句中。可以从分组中忽略它,也可以将其包含在select子句中。请注意,因为[area]是联接的一部分,所以它只能是您在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

修改

另一种方法:

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

修改2

也许一种减少查询迭代次数的方法是将分组扩展到用于选择该数据的所有3列,并扩大where子句的定义方式。还有一种使用values

来产生SizeClassep行的方法。
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

答案 1 :(得分:1)

您在cte和xyzfirms201701中具有相同的列名。您必须在表的任何一个中重命名它,此查询才能起作用。或者,您可以如下创建别名列名称。但是,当您不需要该表中的任何列时,交叉连接在这里就没有意义。它只是创建重复的记录。

以下应该起作用。注意Area列的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