如何在SQL中缩短长UNION ALL查询

时间:2009-02-12 21:41:37

标签: tsql logic

我需要缩短这个查询,虽然我非常擅长SQL,但我还在学习。

    SELECT
        'doejoh',
        DATETIME,
        [Recipient-Address], [Message-Subject], [Sender-Address] 
    FROM
        dbo.Logs 
    WHERE
        LEFT([Recipient-Address], 6) IN ('doejoh') 
UNION ALL 
    SELECT
        'doejoh',
        DATETIME,
        [Recipient-Address], [Message-Subject], [Sender-Address] 
    FROM
        dbo.Logs 
    WHERE
        LEFT([Recipient-Address], 10) IN ('john.doe@g') 
UNION ALL 
    SELECT
        'doejoh',
        DATETIME,
        [Recipient-Address], [Message-Subject], [Sender-Address] 
    FROM
        dbo.Logs 
    WHERE
            LEFT([Sender-Address], 6) IN ('doejoh') 
    UNION ALL 
    SELECT
        'doejoh',
        DATETIME,
        [Recipient-Address], [Message-Subject], [Sender-Address] 
    FROM
        dbo.Logs 
    WHERE
            LEFT([Sender-Address], 10) IN ('john.doe@g')
    ORDER BY
        DateTime

我必须使用此联合,因为在同一个表中,每个用户及其电子邮件地址有4种不同的可能性。话虽这么说,我有30个用户,所以在整个查询中30x4将是120个组。第一列必须是用户名的原因是因为我在Crystal Report中使用该列。

我只是想为我的查询创建一些逻辑来缩短它,同时将每个用户“分配”到适当的第一列。

已编辑添加

虽然这会缩短我的查询,但我仍然需要有30个工会:

SELECT
   'doejoh',
   DATETIME,
   [Recipient-Address], [Message-Subject], [Sender-Address] 
FROM
   dbo.Logs 
WHERE
   LEFT([Recipient-Address], 6) IN ('doejoh') OR
   LEFT([Recipient-Address], 10) IN ('john.doe@g') OR
   LEFT([Sender-Address], 6) IN ('doejoh') OR
   LEFT([Sender-Address], 10) IN ('john.doe@g')
ORDER BY
   DateTime

因为下一个用户将与前一个用户联合:

UNION ALL 
SELECT
   'doejan',
   DATETIME,
   [Recipient-Address], [Message-Subject], [Sender-Address] 
FROM
   dbo.Logs 
WHERE
   LEFT([Recipient-Address], 6) IN ('doejan') OR
   LEFT([Recipient-Address], 10) IN ('jane.doe@g') OR
   LEFT([Sender-Address], 6) IN ('doejan') OR
   LEFT([Sender-Address], 10) IN ('jan.doe@g')

依旧等等......任何更短的方式?

5 个答案:

答案 0 :(得分:5)

您应该将查询重写为:

SELECT
   'doejoh',
   DATETIME,
   [Recipient-Address], [Message-Subject], [Sender-Address] 
FROM
   dbo.Logs 
WHERE
   LEFT([Recipient-Address], 6) IN ('doejoh') OR
   LEFT([Recipient-Address], 10) IN ('john.doe@g') OR
   LEFT([Sender-Address], 6) IN ('doejoh') OR
   LEFT([Sender-Address], 10) IN ('john.doe@g')
ORDER BY
   DateTime

在选择方面应该是相同的,我认为只是更快,更容易理解。

马克

答案 1 :(得分:4)

有这样的事情是行不通的吗?

CREATE TABLE #TempNames
(
    shortname nvarchar(6),
    longname nvarchar(10)
)

INSERT INTO #TempNames (shortname, longname) VALUES('doejoh', 'john.doe@g')
INSERT INTO #TempNames (shortname, longname) VALUES('doejan', 'jan.doe@g')
INSERT INTO #TempNames (shortname, longname) VALUES('smibob', 'bob.smith@g')

SELECT
    #TempName.shortname,
    DATETIME,
    [Recipient-Address], [Message-Subject], [Sender-Address]
FROM
    dbo.Logs
INNER JOIN
    #TempNames
ON
    LEFT([Recipient-Address], 6) = #TempNames.shortname
OR
    LEFT([Recipient-Address], 10) = #TempNames.longname
OR
    LEFT([Sender-Address], 6) = #TempNames.shortname
OR
    LEFT([Sender-Address], 10) = #TempNames.longname

答案 2 :(得分:2)

创建一个映射表并加入它。

例如。

之类的东西
select user_name, DateTime .... 
from Logs
join Users on 
   LEFT([Recipient-Address], 6) IN (user_name) OR
   LEFT([Recipient-Address], 10) IN (user_email) OR
   LEFT([Sender-Address], 6) IN (user_name) OR
   LEFT([Sender-Address], 10) IN (user_email)

答案 3 :(得分:1)

你不能只使用......

SELECT
    'doejoh',
    DATETIME,
    [Recipient-Address], [Message-Subject], [Sender-Address] 
FROM
    dbo.Logs 
 WHERE
    (LEFT([Recipient-Address], 10) IN ('john.doe@g'))
or  (LEFT([Recipient-Address], 6) IN ('doejoh') )
or  ( LEFT([Sender-Address], 10) IN ('john.doe@g'))
or  (LEFT([Sender-Address], 6) IN ('doejoh') )

答案 4 :(得分:1)

创建一个包含30个人的电子邮件地址的表格。 表:电子邮件 列:short6,long10,电子邮件

然后只使用1个联合

Select Emails.short6, Logs.DateTime, Logs.[Recipient-Address], Logs.[Message-Subject], Logs.[Sender-Address]
From Emails JOIN Log on Emails.email = Log.[Recipient-Address]
Where LEFT([Recipient-Address], 6) = Emails.short6 
or LEFT([Recipient-Address], 10) = Emails.long10

union all

Select Emails.short6, Logs.DateTime, Logs.[Recipient-Address], Logs.[Message-Subject], Logs.[Sender-Address]
From Emails JOIN Log on Emails.email = Log.[Sender-Address]
Where LEFT([Sender-Address], 6) = Emails.short6 
or LEFT([Sender-Address], 10) = Emails.long10