2016-12-20 8 views
1

WITH句の中でT1を使用しているので、指定されたクエリはどのように正しいですか?T1はWITH内の句が完了した後に宣言されます。問い合わせの上次のSQLクエリはどのように機能していますか?

WITH T1(Emp,Manager,Salary) AS 
( 
SELECT tt2.[Emp],tt2.[Manager],tt2.[Salary] 
FROM [YourTable] AS tt1 
RIGHT OUTER JOIN [YourTable] AS tt2 ON tt1.[Emp]=tt2.[Manager] 
WHERE tt1.[Emp] is NULL 
UNION ALL 
SELECT r.[Emp],T1.[Manager],r.[Salary] 
FROM [YourTable] AS r 
INNER JOIN T1 ON r.[Manager]=T1.[Emp] 
) 
SELECT [Manager],SUM([Salary]) AS Salary 
FROM T1 
GROUP BY [Manager] 
ORDER BY SUM([Salary]) DESC 

次の質問に答えている - 私は列(従業員、マネージャー、給与)を持つテーブルがある

。 1つのSQLでトップレベルのマネージャーに対応するすべての従業員の総給与を計算する必要があります。例えば

Input table is : 
Emp Manager Salary 
A T 10 
B A 11 
C F 13 
D B 5 

結果は次のようになります。

Top-Lvl Manager Salary(agg) 
T 26 
F 13 

マネージャ - 従業員の階層化は、複数のレベルに行くことができます。

+0

私は互換性のないデータベースタグを削除しました。実際に使用しているデータベースにタグを付けてください。 –

+1

このクエリは、CTE(Comman Table Expression)を使用して構築されています。詳細については、このリンクを参照してください - https://www.codeproject.com/Articles/275645/CTE-In-SQL-Server – LogicalDesk

答えて

4

これは再帰的なクエリです。 UNION ALLの前の部分は基本レコードを取得します。後の部分は、再帰的に前者に追加された行を取得します。

最初の部分は混乱して書かれています。多くの人が読むことが難しいと考えられる右外部結合でも補完される反結合パターンです。これは単にこれを意味します:

select emp, manager, salary 
from yourtable 
where manager not in (select emp from yourtable); 

このように、マネージャーを持たないすべての従業員(スーパーマネージャー)が得られます。

UNION ALLの後の部分では、それらの部下とその下位部を取得します。階層的なクエリ。最後に

SELECT [Manager],SUM([Salary]) AS Salary 
FROM T1 
GROUP BY [Manager] 
ORDER BY SUM([Salary]) DESC 

には、マネージャごとの累積給与を得るためにそれらの行を使用します。

ここでSQL Serverの再帰的なクエリを読むことができます:https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

1

内側withT1INNER JOIN T1 ON r.[Manager]=T1.[Emp]への参照はおそらくDBのテーブルです。 Outside withT1withの結果への参照。

+0

私はそうではないと思います。 T1という名前の他のテーブルはありません。これは、Manager-Employeeのマルチレベルレイヤーのための単一レイヤーに再帰的に行う必要があるため、T1を使用しています。 –

+0

T1テーブルも同義語もないと確信しているのであれば、Thorstenの答えはここではうまくいきます。 – Kacper

2

EDIT - レスオーバー殺す

Declare @YourTable table (Emp varchar(25),Manager varchar(25),Salary int) 
Insert into @YourTable values 
('A','T',10), 
('B','A',11), 
('C','F',13), 
('D','B',5) 

;with cteP as (
     Select Seq = cast(1000+Row_Number() over (Order by Emp) as varchar(500)) 
      ,Emp=Manager 
      ,Manager=cast(null as varchar(25)) 
      ,Lvl=1 
      ,Salary = 0 
     From @YourTable 
     Where Manager Not In (Select Distinct Emp From @YourTable) 
     Union All 
     Select Seq = cast(concat(p.Seq,'.',1000+Row_Number() over (Order by r.Emp)) as varchar(500)) 
      ,r.Emp 
      ,r.Manager 
      ,p.Lvl+1 
      ,r.Salary 
     From @YourTable r 
     Join cteP p on r.Manager = p.Emp) 
Select TopLvl = A.Emp 
     ,Salary = sum(B.Salary) 
from cteP A 
Join cteP B on (B.Seq Like A.Seq+'%') 
Where A.Lvl=1 
Group By A.Emp 

戻り

TopLvl Salary 
F  13 
T  26 
関連する問題