Come accorciare tempo UNION ALL query in SQL
Domanda
Ho bisogno di accorciare questa query e mentre io sono abbastanza bravo a SQL, sto ancora imparando.
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
devo usare questa unione, perché nella stessa tabella, ci sono 4 differenti possibilità per ogni utente e indirizzo email. Detto questo, ho 30 utenti, in modo da 30x4 sarebbero 120 gruppi in questa intera query. La ragione per cui la prima colonna deve essere il nome utente è perché sto utilizzando quella colonna in un report Crystal.
Sto solo cercando di creare una logica per la mia query che si riduce verso il basso, mentre allo stesso tempo "assegnando" ogni utente alla loro appropriata prima colonna.
A cura di aggiungere
Anche se questo ridurrà la mia domanda, dovrò ancora avere 30 sindacati:
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
Poiché l'utente successivo sarebbe unioned alla precedente:
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')
E così via e così via ... un modo più breve?
Soluzione
C'è un motivo qualcosa come questo non funzionerà?
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
Altri suggerimenti
Si dovrebbe riscrivere la query come:
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
dovrebbe essere la stessa in termini di selezione, solo un po 'più veloce e più facile da capire, credo.
Marc |
creare una tabella di mappatura e unirsi ad esso.
ad es. qualcosa come
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)
Non potete usare solo ...
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') )
Crea una tabella con l'indirizzo di posta elettronica delle 30 persone. Tabella: Messaggi di posta elettronica Colonne: short6, long10, e-mail
quindi utilizzando solo 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