2009-02-12 87 views
1

我需要縮短這個查詢,雖然我非常擅長SQL,但我仍然在學習。如何在TSQL中縮短長聯盟所有查詢

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 ('[email protected]') 
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 ('[email protected]') 
    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 ('[email protected]') OR 
    LEFT([Sender-Address], 6) IN ('doejoh') OR 
    LEFT([Sender-Address], 10) IN ('[email protected]') 
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 ('[email protected]') OR 
    LEFT([Sender-Address], 6) IN ('doejan') OR 
    LEFT([Sender-Address], 10) IN ('[email protected]') 

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

+0

如果我有這個正確的,你要找返回5列的一個結果,即發送者地址或收件人地址分別是「doejoh」還是「[email protected]」作爲前6個和10個字符? – 2009-02-12 21:48:36

+0

是否有一個SenderID或RecipientID或其他數字標識符可以用作字符串模式匹配? – 2009-02-12 21:50:12

+0

@Russ Cam - 它必須是一個字符串匹配。 – GregD 2009-02-12 21:53:02

回答

4

是否有這樣的原因是行不通的?

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

INSERT INTO #TempNames (shortname, longname) VALUES('doejoh', '[email protected]') 
INSERT INTO #TempNames (shortname, longname) VALUES('doejan', '[email protected]') 
INSERT INTO #TempNames (shortname, longname) VALUES('smibob', '[email protected]') 

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 
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 ('[email protected]') OR 
    LEFT([Sender-Address], 6) IN ('doejoh') OR 
    LEFT([Sender-Address], 10) IN ('[email protected]') 
ORDER BY 
    DateTime 

應該在選擇上是相同的,只是有點更快,更容易理解,我想。

馬克

1

不能使用只是...

SELECT 
    'doejoh', 
    DATETIME, 
    [Recipient-Address], [Message-Subject], [Sender-Address] 
FROM 
    dbo.Logs 
WHERE 
    (LEFT([Recipient-Address], 10) IN ('[email protected]')) 
or (LEFT([Recipient-Address], 6) IN ('doejoh')) 
or (LEFT([Sender-Address], 10) IN ('[email protected]')) 
or (LEFT([Sender-Address], 6) IN ('doejoh')) 
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) 
1

創建一個包含30個人的電子郵件地址的表格。 表:電子郵件 列:short6,long10,電子郵件

然後只用1個UNION ALL

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