web-dev-qa-db-ja.com

エラー-再帰的選択にCTEを使用する場合、「UNION演算子には同じ数の式が必要です」

現時点では、列ID, Location, PartOfIDを含むテーブルtblLocationがあります。

テーブルはそれ自体に再帰的に接続されています:PartOfID -> ID

私の目標は、次のように選択出力を持つことです。

> France > Paris > AnyCity >

説明: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演算子を使用して結合されたすべてのクエリは、ターゲットリストに同数の式を持っている必要があります。

出力を修正する方法があれば、それは素晴らしいことです。

17
user2871811

問題はここに産みます:

--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_deelVan_LOC_idを2番目の結果セットに追加する必要があると思います

20
Yosi Dahari

二番目 result setには1列しかありませんが、最初のresult set

UNIONを使用する場合、列は一致する必要があります)

最初の列としてIDを追加し、PartOf_LOC_idあなたのresult setので、UNIONを実行できます。

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

次に、結合の両方の部分で列の数が一致する必要があります。

完全なパスを作成するには、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;

これは古い投稿ですが、別の実例を共有しています。

「各ユニオン」OR「ユニオンALL」IS USED "の場合、各カラムのデータ型は一致する必要があります。

例を見てみましょう。

1:

SQLで-SELECT 'column1'、 'column2'(注:引用符で名前を指定することを忘れないでください)結果セットでは、2つのヘッダー(column1およびcolumn2)で空の列が表示されます

2:出会った1つの簡単なインスタンスを共有します。

SQLのデータ型がほとんどない7つの列がありました。つまりuniqueidentifier、datetime、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
_

上記の「inspectionid」列と「documenttype」列にはuniqueidentiferデータ型があり、したがってCONVERT(NVARCHAR(36))が適用されます。列「modifiedon」は日時であるため、CONVERT(NVARCHAR(23), 'modifiedon', 126)が適用されます。

上記の2番目のSELECTクエリと並行して、各列のデータ型ごとに1番目のSELECTクエリに一致しました。

1
Binoy

再帰的なスカラー関数を使用できます:-

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

プロデュース:-

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