【问题标题】:SQL Joining tables with 'constants'SQL 使用“常量”连接表
【发布时间】:2015-07-17 17:29:11
【问题描述】:

我有一张订单表,

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 中的 Email 字段

所有其他位置的 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'

我的问题是 Role No_Filter_Group 有时可能不存在于 Role 表中,这导致上述查询没有返回任何内容。

我如何正确连接这些表,所以如果表中不存在 No_Filter_Group,则 SalesPersonEmailFiltered_Group 的行仍然存在从查询返回?

谢谢

【问题讨论】:

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


    【解决方案1】:

    一种比较简单的方法是使用LEFT JOIN,并在连接条件中输入特殊编号001 代表您的位置和特殊角色名称Filtered_GroupNo_Filter_Group

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

    无论如何,查询都会返回Invoice 表中的所有行。

    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】:

      试试这样的。

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

      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',那么您可以从 sub-query 中删除 TOP 1

      【讨论】:

        【解决方案3】:

        左连接或更简单但效率较低的方法是在 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
        

        通常您会希望将它们相互连接,但我不确定您将如何使用提供的架构来做到这一点。

        【讨论】:

          【解决方案4】:

          将为每一行运行嵌套选择,相反,您可以试试这个:-

          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
          

          【讨论】:

            【解决方案5】:

            使用以下查询:

                  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'
            

            【讨论】:

              猜你喜欢
              • 2017-07-08
              • 2011-07-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-07-02
              • 1970-01-01
              • 1970-01-01
              • 2017-03-28
              相关资源
              最近更新 更多