كيفية تقصير نقابة طويلة كل الاستعلام في Tsql
سؤال
أحتاج إلى تقصير هذا الاستعلام بينما أنا جيد جدا في 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 مجموعة في هذا الاستعلام بأكمله. السبب في أن اسم المستخدم الأول يجب أن يكون اسم المستخدم لأنني أستخدم هذا العمود في تقرير كريستالي.
أنا فقط أتطلع إلى إنشاء بعض المنطق لاستعلامتي التي ستقصيها، في الوقت نفسه، "تعيين" كل مستخدم إلى العمود الأول المناسب.
تم تحريره لإضافة.
في حين أن هذا سيقصر استفسالي، ما زلت يجب أن يكون لديك 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')
وما إلى ذلك وما إلى ذلك ... أي طريقة أقصر؟
المحلول
هل هناك سبب من هذا القبيل لن يعمل؟
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
نصائح أخرى
يجب إعادة كتابة استفسارك باسم:
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
يجب أن يكون هو نفسه من حيث الاختيار، أسرع قليلا وأسهل لفهم، كما أعتقد.
مارك
إنشاء جدول رسم الخرائط والانضمام إليها.
على سبيل المثال شيء مثل
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)
لا يمكنك استخدام فقط ...
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') )
إنشاء جدول مع عنوان البريد الإلكتروني لشخصين. الجدول: أعمدة رسائل البريد الإلكتروني: 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