當使用CTE進行遞歸選擇時,“UNION操作符必須具有相同數量的表達式”。

[英]Error - “UNION operator must have an equal number of expressions” when using CTE for recursive selection


At this moment I have a table tblLocation with columns ID, Location, PartOfID.

此時,我有一個具有列ID、位置和PartOfID的表tblLocation。

The table is recursively connected to itself: PartOfID -> ID

這個表遞歸地連接到它自己:PartOfID -> ID

My goal is to have a select output as followed:

我的目標是得到如下所示的選擇輸出:

> France > Paris > AnyCity >

Explanation: AnyCity is located in Paris, Paris is located in France.

說明:任何城市位於巴黎,巴黎位於法國。

My solution that I found until now was this:

我找到的解決辦法是:

; 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

Unfortunately I get the following error:

不幸的是,我得到了以下錯誤:

All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

所有使用UNION、INTERSECT或EXCEPT操作符組合的查詢必須在其目標列表中具有相同數量的表達式。

If you have any idea how I could fix my output it would be great.

如果你知道我怎么能修正我的輸出,那就太好了。

4 个解决方案

#1


15  

The problem lays here:

這里的問題了:

--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

In order to use union or union all number of columns and their types should be identical cross all result sets.

為了使用union或union,所有列的數目及其類型應該跨所有結果集都是相同的。

I guess you should just add the column LOC_deelVan_LOC_id to your second result set

我想你應該將列loc_developvan_loc_id添加到第二個結果集

#2


3  

Then number of columns must match between both parts of the union.

那么,聯合的兩個部分之間的列數必須匹配。

In order to build the full path, you need to "aggregate" all values of the Location column. You still need to select the id and other columns inside the CTE in order to be able to join properly. You get "rid" of them by simply not selecting them in the outer select:

為了構建完整的路徑,需要“聚合”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;

#3


3  

The second result set have only one column but it should have 3 columns for it to be contented to the first result set

第二個結果集只有一個列,但它應該有3個列,以便滿足第一個結果集。

(columns must match when you use UNION)

(使用UNION時,列必須匹配)

Try to add ID as first column and PartOf_LOC_id to your result set, so you can do the UNION.

嘗試將ID添加為第一列,並將PartOf_LOC_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

#4


0  

You could use a recursive scalar function:-

您可以使用遞歸標量函數:-

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

produces:-

生產:

 > france >
 > france > paris >
 > france > paris > belleville >
 > france > lyon >
 > france > lyon > vaise >
 > united kingdom >
 > united kingdom > england >
 > united kingdom > england > manchester >
 > united kingdom > england > manchester > fallowfield >
 > united kingdom > england > manchester > withington >

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2013/11/30/15556080e43dcc2154b525bf476a29b0.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com