如何使用SQL Server从具有特定条件的两个表中检索数据?

时间:2017-02-19 13:10:55

标签: sql sql-server stored-procedures

我有一个名为 1.ReportTableDetails和2.SecurityDetails

的两个表

ReportTableDetails

ReportName   | ColumnNames | FilterNames
--------------------------------------
Total Sales  | data1,data2 | data1,data2
Branch Sales | data1,data2 | data1,data2

SecurityDetails

SecurityLevel | ReportName   | RColumn     | RFilter
--------------------------------------------------------
     1        | Total Sales  | data1,data2 | data1,data2
     4        | Total Sales  | data1,data2 | data1,data2
  

我将按SecurityLevel from SecurityDetails搜索记录。条件是,如果在 SecurityDetails 中找不到 ReportName ,则应从 ReportTableDetails

中选择数据

期待输出

SecurityLevel | ReportName   | RColumnNames| RFilterNames | ColumnNames | FilterNames
---------------------------------------------------------------------------------------
     1        | Total Sales  | data1,data2 | data1,data2  |             |
     1        | Branch Sales |             |              | data1,data2 | data1,data2

我尝试使用SecurityDetails表进行内连接。它在报告名称相等时检索。但我想检索哪些不在 SecurityDetails 表中

2 个答案:

答案 0 :(得分:1)

您可以使用left join

执行此操作
declare @SecurityLevel int = 1;
select 
      SecurityLevel = isnull(sd.SecurityLevel,@SecurityLevel)
    , ReportName    = isnull(sd.ReportName, rd.ReportName)
    , RColumnNames  = isnull(sd.RColumn,'')
    , RFilterNames  = isnull(sd.RFilter,'')
    , ColumnNames   = case when sd.RColumn is null 
                        then rd.ColumnNames else '' end
    , FilterNames   = case when sd.RFilter is null 
                        then rd.FilterNames else '' end
from ReportTableDetails as rd
  left join SecurityDetails as sd
    on sd.ReportName = rd.ReportName
      and sd.SecurityLevel = @SecurityLevel

返回:

+-------------+---------------+--------------+--------------+--------------+-------------+
|SecurityLevel|  ReportName   | RColumnNames | RFilterNames | ColumnNames  | FilterNames |
+-------------+---------------+--------------+--------------+--------------+-------------+
|           1 | Total Sales   | data1,data2  | data1,data2  |              |             |
|           1 | Branch Sales  |              |              | data1,data2  | data1,data2 |
+-------------+---------------+--------------+--------------+--------------+-------------+

测试设置:http://rextester.com/QGZHLO98381

create table ReportTableDetails (
    ReportName  varchar(64)
  , ColumnNames varchar(64)
  , FilterNames varchar(64)
  );
insert into ReportTableDetails values
    ('Total Sales  ','data1,data2 ','data1,data2')
  , ('Branch Sales ','data1,data2 ','data1,data2');
create table SecurityDetails (
    SecurityLevel int
  , ReportName    varchar(64)
  , RColumn       varchar(64)
  , RFilter       varchar(64)
  );
insert into SecurityDetails values
    (1 ,'Total Sales  ','data1,data2 ','data1,data2')
  , (4 ,'Total Sales  ','data1,data2 ','data1,data2');
/* ---------------------------------------------------*/
declare @SecurityLevel int = 1;
select 
      SecurityLevel = isnull(sd.SecurityLevel,@SecurityLevel)
    , ReportName    = isnull(sd.ReportName, rd.ReportName)
    , RColumnNames  = isnull(sd.RColumn,'')
    , RFilterNames  = isnull(sd.RFilter,'')
    , ColumnNames   = case when sd.RColumn is null 
                        then rd.ColumnNames else '' end
    , FilterNames   = case when sd.RFilter is null 
                        then rd.FilterNames else '' end
from ReportTableDetails as rd
  left join SecurityDetails as sd
    on sd.ReportName = rd.ReportName
      and sd.SecurityLevel = @SecurityLevel

答案 1 :(得分:0)

这是复杂的,因为即使没有匹配项也需要安全级别。

我认为以下是您想要的:

select sl.SecurityLevel, rd.ReportName,
       sd.RColumnNames, sd.RFilterNames,
       (case when sd.SecurityLevel then rd.columnNames end) as columnMames,
       (case when sd.SecurityLevel then rd.FilterNames end) as FilterNames
from (select distinct sd.SecurityLevel from SecurityDetails sd where  sd.SecurityLevel = 1) sl cross join
     reportdetails rd left join                  
     on sd.ReportName = rd.ReportName and
        sd.SecurityLevel = sl.SecurityLevel;

sl子查询看起来很奇怪(它只返回一行)。但这可以推广到更高的安全级别。