SQL将表连接到'常量'

时间:2015-07-17 04:54:51

标签: sql sql-server sql-server-2008 tsql

我有一张订单表,

Invoice   Location    Customer Code   SalesPersonEmail
------------------------------------------------------
300001    001         CUS001          ?
300002    006         CUS002          ?

一个电子邮件组表,

Role              Email 
-----------------------------------------------------
Filtered_Group    Management@gmail.com;john@gmail.com

当Location = 001时,SalesPersonEmail必须是Filtered_Group的电子邮件字段

所有其他地点的SalesPersonEmail必须是" Orders@gmail.com;" +角色电子邮件No_Filter_Group。

我目前正在使用以下内容来实现这一目标,

SELECT i.Invoice, i.Location, i.[Customer Code], 
    CASE WHEN i.Location = 001 
         THEN f.Email 
         ELSE N'Orders@gmail.com;' + nf.Email as SalesPersonEmail
    END
FROM   Invoice i, RoleCodes f, RoleCodes nf
WHERE  f.Role = N'Filtered_Group' AND nf.Role = N'No_Filter_Group'

我的问题是角色No_Filter_Group有时可能不存在于Role表中,导致上述查询什么都不返回。

如何正确加入这些表,以便如果表中不存在 No_Filter_Group ,那么 SalesPersonEmail Filtered_Group 的行仍然存在从查询返回?

由于

5 个答案:

答案 0 :(得分:1)

尝试这样的事情。

注意:这只是一个示例,我不确定架构的表和列。替换为相应的表和列

SELECT CASE 
         WHEN location = '001' THEN (SELECT TOP 1 email 
                                     FROM   email_table 
                                     WHERE  [role] = 'Filtered_Group') 
         ELSE 'Orders@gmail.com;' 
       END 
FROM   orders 

如果email_table表只有一行[role] = 'Filtered_Group',那么您可以从TOP 1

中删除sub-query

答案 1 :(得分:1)

一种相对简单的方法是使用LEFT JOIN并为您的位置添加特殊号码001,并在加入条件中添加特殊角色名称Filtered_GroupNo_Filter_Group

在此SQL Fiddle中,您可以对架构定义中的一行进行评论/取消注释,以便在RoleCodes有一行No_Filter_Group时以及当它没有行时查看它是如何工作的。

在任何情况下,查询都会返回Invoice table。

中的所有行
SELECT
  Invoice.Invoice
  ,Invoice.Location
  ,Invoice.[Customer Code]
  ,CASE WHEN Invoice.Location = '001'
  THEN RoleCodes.Email
  ELSE 'Orders@gmail.com;' + ISNULL(RoleCodes.Email, '')
  END AS SalesPersonEmail
FROM
  Invoice
  LEFT JOIN RoleCodes ON
    (Invoice.Location = '001' 
    AND RoleCodes.Role = 'Filtered_Group')
    OR
    (Invoice.Location <> '001' 
    AND RoleCodes.Role = 'No_Filter_Group')

答案 2 :(得分:0)

左连接或更简单但效率更低的方法是在select语句本身中执行子查询。

SELECT i.Invoice, i.Location, i.[Customer Code], 
    CASE WHEN i.Location = 001 
             THEN (SELECT TOP 1 f.Email FROM RoleCodes f WHERE f.Role = N'Filtered_Group')
         ELSE N'Orders@gmail.com;' + ISNULL( (SELECT nf.Email as SalesPersonEmail FROM  RoleCodes nf WHERE nf.Role = N'No_Filter_Group'), '')
    END
FROM   Invoice i

通常你会希望将它们加入到彼此中,但我不确定如何使用提供的模式来实现这一点。

答案 3 :(得分:0)

将为每一行运行嵌套选择,您可以尝试: -

Select   i.Invoice
        ,i.Location
        ,i.CustomerCode
        ,Isnull(r.Email,'Orders@gmail.com') As SalesPersonEmail
From    Invoice As i With (Nolock)
        Left Join 
        (
            Select   rc.Email
                    ,'001' As Location
            From    RoleCodes As rc With (Nolock)
            Where   rc.Role = 'Filtered_Group'
        ) As r On i.Location = r.Location

答案 4 :(得分:0)

使用以下查询:

      select t.Invoice,t.Location,t.[Customer Code],
      case t.Location
      when '001' then 
           t2.Email
      else
          'Orders@gmail.com'
      end
      as 
      Salespersonemail
      from orders t
      join email_groups t2 on t2.Role='Filtered_Group'