2017-12-13 18 views
1

これらは2 tablesone-to-many関係を有するされています1対多の関係データの取得方法

Employee[Table]: 
--------------------------------------------------- 
EmpId | Name | Country | Salary | Email 
-------------------------------------------------- 
1   John USA  875847 [email protected] 
2   Mike USA  785487 [email protected] 

Lincense[Table] 
---------------------------------------- 
EmpId | LicenseType | LincenseNumber 
---------------------------------------- 
1   LincenseType1 12345678 
1   LincenseType2 87654321 
1   LincenseType3 78945613 
2   LincenseType1 12345678 
2   LincenseType2 87654321 
2   LincenseType3 78945613 


EmployeeDetails[Expected ResulSet] 
----------------------------------------------------------------------------------------------- 
EmpId | Name | Country | LicenseType  | LicenseNumber | Salary | Email 
----------------------------------------------------------------------------------------------- 
1   John USA  LincenseType1   12345678 875847  [email protected] 
          LincenseType2   87654321 
          LincenseType3   78945613 
2   Mike USA  LincenseType1   12345678 785487  [email protected] 
          LincenseType2   87654321 
          LincenseType3   78945613 
---------------------------------------------------------------------------------------------- 

その結果はEmployee詳細および関連するすべてのLicense詳細については、1行しか含まれているので、それを達成するための最良の方法であるものと予想形式の上で結果を取得するには?

+0

参加してください。しかし、EmpIdまたはNameの空の値は取得されません。これは、データベースではなくプレゼンテーション層で処理する必要があります。 –

+0

@SamKuhmonen、私は参加しようとしましたが、特定のユーザーのすべての行についてID、名前、国、給与、電子メールを繰り返します。 – JMD

+0

はい、私はそれがプレゼンテーション層が処理する仕事だと言いました。データベースではありません。それは、データベースがあなたのためにそれをやろうとするよりもずっと簡単です。 –

答えて

2

これはあなたのためのトリックを行います。あなたのempidと給料がint列の場合は、nullしか入力できないか、0にすることを忘れないでください。 Lincencetypeはいつもあなたはこのようにそれを行うだけでできる最初の行に1をする必要がある場合はそれ以外の場合は、タイプstring

SQLコード

declare @emp table (empid int,[name] nvarchar(50),Country nvarchar(50),Salary int,[Email] nvarchar(50) 
) 
insert into @emp 
values 
(1   ,'John', 'USA',  875847, '[email protected]'), 
(2   ,'Mike', 'USA',  785487, '[email protected]') 

declare @lic table (empid int, licensetype nvarchar(50),licencenumber int) 
insert into @lic 
values 



(1   ,'LincenseType1', 12345678), 
(1   ,'LincenseType2', 87654321), 
(1   ,'LincenseType3', 78945613), 
(2   ,'LincenseType1', 12345678), 
(2   ,'LincenseType2', 87654321), 
(2   ,'LincenseType3', 78945613) 

select 
empid = case when rn > 1 then null else x.empid end, 
[name] = case when rn > 1 then '' else [name] end, 
Country = case when rn > 1 then '' else country end, 
licensetype = licensetype, 
licencenumber = licencenumber, 
Salary = case when rn > 1 then '' else Salary end, 
Email = case when rn> 1 then '' else Email end 

from (
select a.empid,[name],country,licensetype,licencenumber,Salary,Email,ROW_NUMBER() over(partition by a.empid order by licensetype) as rn from @emp a left join @lic b on a.empid = b.empid 
)x 

SQL更新 のようにする必要があります。それはあなたの空白行を与えることはありませんが、入れます

SELECT A.EMPID, A.NAME, A.COUNTRY, STUFF((SELECT ','+ b.LicenseType FROM License b WHERE A.EMPID = B.EMPID FOR XML PATH('')),1,1,'') AS LicenseType, STUFF((SELECT ','+ C.LicenseNumber FROM License C WHERE A.EMPID = C.EMPID FOR XML PATH('')),1,1,'') AS LicenseNumber, A.Salary, A.Email 
FROM Employee A 

:これは

select 
empid = case when licensetype !='LincenseType1' then null else a.empid end, 
[name] = case when licensetype !='LincenseType1' then '' else [name] end, 
Country = case when licensetype !='LincenseType1' then '' else country end, 
licensetype = licensetype, 
licencenumber = licencenumber, 
Salary = case when licensetype !='LincenseType1' then '' else Salary end, 
Email = case when licensetype !='LincenseType1' then '' else Email end 


from @emp a inner join @lic b on a.empid = b.empid 

結果

enter image description here

+0

作業中ですが、実際のシナリオでは実行に多くの時間がかかります。 – JMD

+0

@JMDはい、重いことがあります。左の代わりに内側の結合がbtwに参加する。 – plaidDK

+0

@JMD私の更新を見てください。あなたがそのルールを使用できるかどうかは分かりませんが、それはより速くなります。 – plaidDK

0

これはいかがですか?

SELECT Employee.EmpId, Employee.Name, Employee.Country, 
     Lincense.LicenseType, Lincense.LincenseNumber, 
     Employee.Salary, Employee.Email 
    FROM Employee JOIN Lincense 
     ON (Employee.EmpId = Lincense.EmpId); 

あなたが示されているように空の値を探している場合は、最善のアプローチは、あなたのレポートツールでそれを行うのではなくSQL

0
SELECT Employee.EmpId, Employee.Name, Employee.Country, 
     Lincense.LicenseType, Lincense.LincenseNumber, 
     Employee.Salary, Employee.Email 
FROM Employee 
JOIN Lincense ON Employee.EmpId = Lincense.EmpId; 

はあなたにsimmilar結果を与えることをやろうとしていることですすべての行にデータが入力されます。

SELECT Employee.EmpId, Employee.Name, Employee.Country, 
     Lincense.LicenseType, Lincense.LincenseNumber, 
     Employee.Salary, Employee.Email 
FROM Employee 
LEFT OUTER JOIN Lincense ON Employee.EmpId = Lincense.EmpId; 

は、すべての従業員のためになるあなたを与えるだろう、それは免許を持っていない場合でも、あなたはLincenceのプロパティ

SELECT Employee.EmpId, Employee.Name, Employee.Country, 
     Lincense.LicenseType, Lincense.LincenseNumber, 
     Employee.Salary, Employee.Email 
FROM Employee 
RIGHT OUTER JOIN Lincense ON Employee.EmpId = Lincense.EmpId; 

にヌルを持つことにより、それらの行に気づくでしょうしても、すべてのライセンスのためになるあなたを与えるだろう従業員が存在しない場合は、従業員のプロパティにNULLを設定してこれらの行に気付くでしょう。

空の行が必要な場合は、DBでそれを行うことをお勧めします。結果を取得したら、バックエンドコードで処理します。または、フロントエンドに結果を表示するときだけです。

あなたが好む英語に応じて、ライセンスまたはライセンスです。

0

これは何をしたいが、十分に近接していない高速になりますLicenseTypeとLicenseNumberはカンマで区切られた同じ列にあります。

関連する問題