簡體   English   中英

連接兩個表,如果第一個表的值為空,但第二個表具有值,則取第二個表的值

[英]Join two tables and if the value on the first table is null, but second table has values, take the values of the second table

我有用戶和組。 可以授予他們每個人在表上執行某項操作的權限(例如“ SELECT”,“ INSERT”等)。 現在,我想創建一個包含用戶名及其權限的表。

  • 因此,如果用戶沒有進行特定的權限SELECT形式tableA ,但他卻是一群IT,其有權在SELECTtableA ,他的TableA上的權限應該是SELECT ,而不是NULL

  • 用戶應具有多個權限。

  • 如果用戶具有至少一項權利(無論是特定於用戶還是組),則應顯示所有權利

  • 如果用戶沒有權限,則應顯示NULL

這是我的示例表:

  • MEWO\\STFL在NO組中,並且具有select/insert特定權限
  • MEWO\\GEIMIT小組中,並且得到了特定的insert權限。
  • MEWO\\WADIT小組中,並且具有特定的權限來select
  • MEWO\\OZFIT小組中,但沒有特定的權限
  • MEWO\\BIA不是組IT ,沒有特定的權限
  • IT是一個團體,已經獲得select權限

表1(單用戶許可)

表格1

表2(經小組許可的小組成員)

表2

預期產量

一張表,其中包含以下輸入:

  • MEWO\\STFL與表1相同
  • MEWO\\GEIM具有insert/select
  • MEWO\\WAD與表1相同
  • MEWO\\OZF具有selectINSTEAD為
  • MEWO\\BIANULL

UNION這兩個表已經使我關閉,但是有重復項。

您可以使用coalesce()函數:

select coalesce(t1.permission_name, t2.permission_name) as permission_name ,
       t1.name
from table2 t2 left join
     table1 t1
     on t1.name = t2.username;

對於當前的嘗試我沒有找到任何P ALISE。

編輯 :也許您需要FULL OUTER JOIN但您的預期輸出並不表明這一點。

select coalesce(t1.permission_name, t2.permission_name) as permission_name ,
           t1.name
from table1 t1 full outer join
     table2 t2
     on t1.name = t2.username;

編輯:我想你想要row_number函數:

with t as (
     select permission_name, name
     from table1
     union all
     select permission_name, username
     from table1
)   

select top (1) with ties *
from t
order by row_number() over (partition by name, permission_name order by name);

這是一個經過修改的查詢,用於捕獲您要查找的內容。

DECLARE @TABLE1 TABLE(PermissionName varchar(20), DName varchar(20))
INSERT INTO @TABLE1
SELECT 'INSERT', 'MEWO\STFL' UNION ALL
SELECT 'SELECT', 'MEWO\STFL' UNION ALL
SELECT  NULL, 'MEWO\BIA' UNION ALL
SELECT 'SELECT', 'MEWO\WAD' UNION ALL
SELECT 'INSERT', 'MEWO\GEIM' UNION ALL
SELECT NULL, 'MEWO\OZF' 



DECLARE @TABLE2 TABLE(PermissionName varchar(20), UserName varchar(20))
INSERT INTO @TABLE2
SELECT 'SELECT', 'MEWO\WAD' UNION ALL
SELECT 'SELECT', 'MEWO\GEIM' UNION ALL
SELECT 'SELECT', 'MEWO\OZF' 



;with Permission as
(
SELECT DName,  PermissionName, RowNum=ROW_NUMBER()over(PARTITION BY DName ORDER BY LEN(PermissionName) DESC)

        FROM 
        (
            select * from @TABLE1
            union 
            select * from @TABLE2
        )g

)




SELECT  
    PM.DName, 
    PC1.PermissionName+
    CASE WHEN PC2.PermissionName IS NOT NULL  THEN '/'+PC2.PermissionName
    ELSE ''
    END
from
 (SELECT DISTINCT DName FROM Permission) PM

 LEFT JOIN Permission PC1 ON
    PC1.DName=PM.DName
    AND
    PC1.RowNum=1

 LEFT JOIN Permission PC2 ON  ---depending on the number of permissions you might have to add more joins
    PC2.DName=PM.DName
    AND
    PC2.RowNum=2
 order by
 1

結果如下: 在此處輸入圖片說明

我想這可以滿足您的條件:

SELECT
    permission_name
    , name
FROM
    (
    SELECT
        coalesce(t2.permission_name, t1.permission_name) as permission_name
        , t1.name AS name
    FROM 
        table1
        LEFT JOIN table2
            ON t1.name = t2.username
    ) AS _temp
WHERE
    NOT _temp.permission_name IS NULL

我假設您不希望其中t1.permission_name為null且t2.permission_name也為NULL或什至t2沒有該條目的行的行-因此是外部查詢(_temp)。 如果您不需要,則完全刪除外部查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM