2017-11-08 11 views
3

以下のクエリは計画通りに動作しますが、参加した方法を正確に示していますが、問題はありませんが、ユーザーにとってより多くの「特殊化」テーブルがあれば、メールタイプ "またはそれ以上のユーザーが1つ以上のデータを持つことができるようにするには... "give priority"からISNULL経由でT-SQL左結合2回

2つの結合を使用しないでください1つの参加でTypeId 1を超えてTypeId 2に優先度を「与える」ことは可能ですか?

if object_id('tempdb..#Tab1') is not null drop table #Tab1 
create table #Tab1 (UserId int, TypeId int) 
if object_id('tempdb..#Tab2') is not null drop table #Tab2 
create table #Tab2 (TypeId int, TypeDescription nvarchar(50)) 

insert into #Tab1 (UserId, TypeId) 
values 
(1, 1), 
(1, 2) 
insert into #Tab2 (TypeId, TypeDescription) 
values 
(1, 'User'), 
(2, 'Admin') 

select *, ISNULL(t2.TypeDescription, t3.TypeDescription) [Role] 
from #Tab1 t1 
    LEFT JOIN #Tab2 t2 on t1.TypeId = t2.TypeId and 
          t2.TypeId = 2 
    LEFT JOIN #Tab2 t3 on t1.TypeId = t3.TypeId and 
          t3.TypeId = 1 

答えて

3

最初の問題は優先度を決定することです。この場合、最大のTypeIdを使用できますが、それは素晴らしい考えのようには見えません。別の列を追加して優先順位序数として使用することもできます。

そこから、それはグループクエリにつきトップ1です:

top with tiesrow_number()を使用して:

common table expressionrow_number()を使用して
select top 1 with ties 
    t1.UserId, t1.TypeId, t2.TypeDescription 
from #Tab1 t1 
    left join #Tab2 t2 
    on t1.TypeId = t2.TypeId 
order by row_number() over (
     partition by t1.UserId 
     order by t2.Ordinal 
     --order by t1.TypeId desc 
) 

:用

;with cte as (
select t1.UserId, t1.TypeId, t2.TypeDescription 
    , rn = row_number() over (
     partition by t1.UserId 
     order by t2.Ordinal 
     --order by t1.TypeId desc 
    ) 
from #Tab1 t1 
    left join #Tab2 t2 
    on t1.TypeId = t2.TypeId 
) 
select UserId, TypeId, TypeDescription 
from cte 
where rn = 1 

rextesterデモ両方:http://rextester.com/KQAV36173

リターンの両方:

+--------+--------+-----------------+ 
| UserId | TypeId | TypeDescription | 
+--------+--------+-----------------+ 
|  1 |  2 | Admin   | 
+--------+--------+-----------------+ 
+1

'ties'でトップが存在することを...助けるためにVeljko89ハッピー@説明 – Veljko89

+0

をありがとうさえ気づいていませんでした! – SqlZim

0

実際に私はあなたがすべてに参加する必要はありませんとは思いません。しかし、TypeDescriptionに関係なく、最大のTypeIDを取らなければなりません。なぜなら、これらの違いがGroup Byを倒す可能性があるからです。回避策は、TypeDescriptionなしでMaxを最初に取り出し、結果をサブクエリしてTypeDescriptionを取得することです。

SELECT dT.* 
     ,(SELECT TypeDescription FROM #Tab2 T2 WHERE T2.TypeId = dT.TypeId) [Role] --2. Subqueries TypeDescription using the Max TypeID 
    FROM (
     select t1.UserId 
       ,MAX(T1.TypeId) [TypeId] 
       --, T1.TypeDescription AS [Role] --1. differences will defeat group by. Subquery for value later in receiving query. 
      from #Tab1 t1     
     GROUP BY t1.UserId 
     ) AS dT 

は出力を生成します。

UserId TypeId Role 
1  2  Admin