Sql 错误-“;并集运算符必须具有相等数量的表达式;使用CTE进行递归选择时

Sql 错误-“;并集运算符必须具有相等数量的表达式;使用CTE进行递归选择时,sql,sql-server,tsql,recursive-query,Sql,Sql Server,Tsql,Recursive Query,此时,我有一个表tballocation,其中包含列ID、Location、PartOfID 该表以递归方式连接到自身:PartOfID->ID 我的目标是获得如下选择输出: > France > Paris > AnyCity > 说明:任何城市都位于巴黎,巴黎位于法国 到目前为止,我找到的解决方案是: ; with q as ( select ID,Location,PartOf_LOC_id from tblLocatie t where t.ID = 1 --

此时,我有一个表
tballocation
,其中包含列
ID、Location、PartOfID

该表以递归方式连接到自身:
PartOfID->ID

我的目标是获得如下选择输出:

> France > Paris > AnyCity >
说明:任何城市都位于巴黎,巴黎位于法国

到目前为止,我找到的解决方案是:

; with q as (
select ID,Location,PartOf_LOC_id from tblLocatie t
where t.ID = 1 -- 1 represents an example
union all
select t.Location + '>' from tblLocation t
inner join q parent on parent.ID = t.LOC_PartOf_ID
)
select * from q
不幸的是,我得到了以下错误:

使用UNION、INTERSECT或EXCEPT运算符组合的所有查询在其目标列表中的表达式数必须相等

如果您知道如何修复输出,那就太好了。

问题在于:

--This result set has 3 columns
select LOC_id,LOC_locatie,LOC_deelVan_LOC_id from tblLocatie t
where t.LOC_id = 1 -- 1 represents an example

union all

--This result set has 1 columns   
select t.LOC_locatie + '>' from tblLocatie t
inner join q parent on parent.LOC_id = t.LOC_deelVan_LOC_id
为了使用
union
union-all
所有结果集的列数及其类型应相同


我想您应该将列
LOC\u deelVan\u LOC\u id
添加到第二个结果集中

您可以使用递归标量函数:-

set nocount on

create table location (
    id int,
    name varchar(50),
    parent int
)
insert into location values
    (1,'france',null),
    (2,'paris',1),
    (3,'belleville',2),
    (4,'lyon',1),
    (5,'vaise',4),
    (6,'united kingdom',null),
    (7,'england',6),
    (8,'manchester',7),
    (9,'fallowfield',8),
    (10,'withington',8)
go
create function dbo.breadcrumb(@child int)
returns varchar(1024)
as begin
    declare @returnValue varchar(1024)=''
    declare @parent int
    select @returnValue+=' > '+name,@parent=parent
    from location
    where id=@child
    if @parent is not null
        set @returnValue=dbo.breadcrumb(@parent)+@returnValue
    return @returnValue
end
go

declare @location int=1
while @location<=10 begin
    print dbo.breadcrumb(@location)+' >'
    set @location+=1
end

第二个
结果集
只有一列,但它应该有三列才能满足第一个
结果集

(使用
UNION
时,列必须匹配)

尝试将
ID
添加为第一列,并将
PartOf_LOC\u ID
添加到
结果集
,这样您就可以执行
联合

;
WITH    q AS ( SELECT   ID ,
                    Location ,
                    PartOf_LOC_id
           FROM     tblLocation t
           WHERE    t.ID = 1 -- 1 represents an example
           UNION ALL
           SELECT   t.ID ,
                    parent.Location + '>' + t.Location ,
                    t.PartOf_LOC_id
           FROM     tblLocation t
                    INNER JOIN q parent ON parent.ID = t.LOC_PartOf_ID
         )
SELECT  *
FROM    q

然后,联合的两个部分之间的列数必须匹配

为了构建完整路径,您需要“聚合”
Location
列的所有值。您仍然需要选择CTE中的id和其他列,以便能够正确连接。您只需不在外部选择中选择它们即可“摆脱”它们:

with q as 
(
   select ID, PartOf_LOC_id, Location, ' > ' + Location as path
   from tblLocation 
   where ID = 1 

   union all

   select child.ID, child.PartOf_LOC_id, Location, parent.path + ' > ' + child.Location 
   from tblLocation child
     join q parent on parent.ID = t.LOC_PartOf_ID
)
select path
from q;

虽然这是一篇老文章,但我正在分享另一个工作示例

“使用“UNION”或“UNION ALL”时,列计数以及每个列数据类型必须匹配”

让我们举一个例子:

1: 在SQL中,如果我们写-选择'column1','column2' (注意:请记住在引号中指定名称) 在结果集中,它将显示两个标题为column1和column2的空列

2:我有一个简单的例子。 我在SQL中有七列,几乎没有不同的数据类型。即唯一标识符、日期时间、nvarchar

我的任务是检索带有列标题的逗号分隔结果集。因此,当我将数据导出到CSV时,我有逗号分隔的行,第一行作为标题,并且有各自的列名

SELECT CONVERT(NVARCHAR(36), 'Event ID') + ', ' + 
'Last Name' + ', ' + 
'First Name' + ', ' + 
'Middle Name' + ', ' + 
CONVERT(NVARCHAR(36), 'Document Type') + ', ' + 
'Event Type' + ', ' + 
CONVERT(VARCHAR(23), 'Last Updated', 126)

UNION ALL

SELECT CONVERT(NVARCHAR(36), inspectionid) + ', ' + 
       individuallastname + ', ' + 
       individualfirstname + ', ' + 
       individualmiddlename + ', ' +
       CONVERT(NVARCHAR(36), documenttype) + ', ' + 
       'I' + ', ' +
       CONVERT(VARCHAR(23), modifiedon, 126)
FROM Inspection
上面,“检查ID”和“documenttype”列具有
uniqueidentifer
datatype,因此应用了
CONVERT(NVARCHAR(36))
。“modifiedon”列是datetime,因此应用于
CONVERT(NVARCHAR(23),“modifiedon”,126)


与上面的第二个
SELECT
querymatched1st
SELECT
query根据每列的数据类型进行查询。

True,但即使我将它们相等,也会出现以下错误:递归查询“q”的列“ID”中的锚和递归部分之间的类型不匹配。Yosi,实际上认为第二个SELECT有一个列“ll select t.Location+'>'”。但是,如果您不同意您的回答,则两个选项的列数必须相同。@Asantabala-您是对的。我更正了这一点。@user2871811,请参阅问题的编辑,类型也应该匹配。错误消息有什么不清楚的地方吗?
SELECT CONVERT(NVARCHAR(36), 'Event ID') + ', ' + 
'Last Name' + ', ' + 
'First Name' + ', ' + 
'Middle Name' + ', ' + 
CONVERT(NVARCHAR(36), 'Document Type') + ', ' + 
'Event Type' + ', ' + 
CONVERT(VARCHAR(23), 'Last Updated', 126)

UNION ALL

SELECT CONVERT(NVARCHAR(36), inspectionid) + ', ' + 
       individuallastname + ', ' + 
       individualfirstname + ', ' + 
       individualmiddlename + ', ' +
       CONVERT(NVARCHAR(36), documenttype) + ', ' + 
       'I' + ', ' +
       CONVERT(VARCHAR(23), modifiedon, 126)
FROM Inspection