تعليمات استعلام SQL:تحويل التواريخ بطريقة غير تافهة
-
01-07-2019 - |
سؤال
لدي جدول يحتوي على عمود "التاريخ"، وأرغب في إجراء استعلام يقوم بما يلي:
إذا كان التاريخ أ الاثنين, يوم الثلاثاء, الأربعاء, ، أو يوم الخميس, ، يجب أن يتم نقل التاريخ المعروض بمقدار يوم واحد، كما في
DATEADD(day, 1, [Date])ومن ناحية أخرى، إذا كان أ جمعة, ، يجب زيادة التاريخ المعروض بمقدار 3 أيام (أي 3 أيام).فيصبح على النحو التالي الاثنين).
كيف أفعل ذلك في بيان SELECT الخاص بي؟كما في،
SELECT somewayofdoingthis([Date]) FROM myTable
(هذا هو SQL Server 2000.)
المحلول
هنا كيف سأفعل ذلك.أوصي بوظيفة مثل المذكورة أعلاه إذا كنت ستستخدمها في أماكن أخرى.
CASE
WHEN
DATEPART(dw, [Date]) IN (2,3,4,5)
THEN
DATEADD(d, 1, [Date])
WHEN
DATEPART(dw, [Date]) = 6
THEN
DATEADD(d, 3, [Date])
ELSE
[Date]
END AS [ConvertedDate]
نصائح أخرى
CREATE FUNCTION dbo.GetNextWDay(@Day datetime)
RETURNS DATETIME
AS
BEGIN
DECLARE @ReturnDate DateTime
set @ReturnDate = dateadd(dd, 1, @Day)
if (select datename(@ReturnDate))) = 'Saturday'
set @ReturnDate = dateadd(dd, 2, @ReturnDate)
if (select datename(@ReturnDate) = 'Sunday'
set @ReturnDate = dateadd(dd, 1, @ReturnDate)
RETURN @ReturnDate
END
يحاول
select case when datepart(dw,[Date]) between 2 and 5 then DATEADD(dd, 1, [Date])
when datepart(dw,[Date]) = 6 then DATEADD(dd, 3, [Date]) else [Date] end as [Date]
أفترض أنك تريد أيضًا نقل يومي السبت والأحد إلى يوم الاثنين التالي.إذا لم يكن الأمر كذلك، خذ الرقم 1 من (1،2،3،4،5) وأزل جملة متى الأخيرة.
case
--Sunday thru Thursday are shifted forward 1 day
when datepart(weekday, [Date]) in (1,2,3,4,5) then dateadd(day, 1, [Date])
--Friday is shifted forward to Monday
when datepart(weekday, [Date]) = 6 then dateadd(day, 3, [Date])
--Saturday is shifted forward to Monday
when datepart(weekday, [Date]) = 7 then dateadd(day, 2, [Date])
end
يمكنك أيضًا القيام بذلك في سطر واحد:
select dateadd(day, 1 + (datepart(weekday, [Date])/6) * (8-datepart(weekday, [Date])), [Date])
يبدو وكأنه تعبير CASE.لا أعرف كيفية معالجة البيانات المناسبة لـ SQL Server، ولكن في الأساس سيبدو الأمر كما يلي:
CASE
WHEN [Date] is a Friday THEN DATEADD( day, 3, [Date] )
ELSE DATEADD( day, 1, [Date] )
END
إذا أردت التحقق من أيام عطلة نهاية الأسبوع، فيمكنك إضافة عبارات WHEN إضافية قبل ELSE.
يمكنك استخدام هذا:
select dayname,newdayname =
CASE dayname
WHEN 'Monday' THEN 'Tuesday'
WHEN 'Tuesday' THEN 'Wednesday'
WHEN 'Wednesday' THEN 'Thursday'
WHEN 'Thursday' THEN 'Friday'
WHEN 'Friday' THEN 'Monday'
WHEN 'Saturday' THEN 'Monday'
WHEN 'Sunday' THEN 'Monday'
END
FROM UDO_DAYS
results: Monday Tuesday Tuesday Wednesday Wednesday Thursday Thursday Friday Friday Monday Saturday Monday Sunday Monday table data: Monday Tuesday Wednesday Thursday Friday Saturday Sunday
ابحث عن عبارة CASE وبيان DATEPART.ستحتاج إلى استخدام الوسيطة dw مع DATEPART لاستعادة عدد صحيح يمثل اليوم من الأسبوع.
هذا خارج رأسي ويمكن تنظيفه بوضوح ولكن استخدمه كنقطة بداية:
select case when DATENAME(dw, [date]) = 'Monday' then DATEADD(dw, 1, [Date])
when DATENAME(dw, [date]) = 'Tuesday' then DATEADD(dw, 1, [Date])
when DATENAME(dw, [date]) = 'Wednesday' then DATEADD(dw, 1, [Date])
when DATENAME(dw, [date]) = 'Thursday' then DATEADD(dw, 1, [Date])
when DATENAME(dw, [date]) = 'Friday' then DATEADD(dw, 3, [Date])
end as nextDay
...
ماذا عن أخذ صفحة من مستودع البيانات يا رفاق وصنعوا طاولة.من حيث DW، سيكون هذا بُعدًا للتاريخ.أ بُعد التاريخ القياسي قد تحتوي على أشياء مثل أسماء مختلفة للتاريخ ("MON"، "الاثنين"، "22 أغسطس 1998")، أو مؤشرات مثل نهاية الشهر وبداية الشهر.ومع ذلك، يمكنك أيضًا الحصول على أعمدة ذات معنى فقط في بيئتك.
على سبيل المثال، بناءً على السؤال، قد يحتوي سؤالك على عمود ليوم العمل التالي يشير إلى مفتاح اليوم المعني.وبهذه الطريقة يمكنك تخصيصه بشكل أكبر ليأخذ في الاعتبار أيام العطل أو أيام العطل الأخرى.
يصر العاملون في DW على استخدام مفاتيح لا معنى لها (أي لا تستخدم فقط تاريخًا مقطوعًا كمفتاح، بل استخدم مفتاحًا تم إنشاؤه)، ولكن يمكنك أن تقرر ذلك بنفسك.
ال مجموعة أدوات أبعاد التاريخ يحتوي على رمز لإنشاء الجداول الخاصة بك في أنظمة إدارة قواعد البيانات المختلفة ويحتوي على بيانات CSV لعدة سنوات من التواريخ.
تحتاج إلى إنشاء دالة SQL تقوم بهذا التحويل نيابةً عنك.
هذا يشبه في الغالب Brian's باستثناء أنه لم يتم تجميعه بسبب عدم تطابق الأقواس وقمت بتغيير IF حتى لا يكون التحديد فيه.من المهم ملاحظة أننا نستخدم DateNAME هنا بدلاً من datePART لأن datePART يعتمد على القيمة التي تم تعيينها بواسطة SET DATEFIRST، والتي تحدد اليوم الأول من الأسبوع.
CREATE FUNCTION dbo.GetNextWDay(@Day datetime)
RETURNS DATETIME
AS
BEGIN
DECLARE @ReturnDate DateTime
set @ReturnDate = dateadd(dd, 1, @Day)
if datename(dw, @ReturnDate) = 'Saturday'
set @ReturnDate = dateadd(dd, 2, @ReturnDate)
if datename(dw, @ReturnDate) = 'Sunday'
set @ReturnDate = dateadd(dd, 1, @ReturnDate)
RETURN @ReturnDate
END
create table #dates (dt datetime)
insert into #dates (dt) values ('1/1/2001')
insert into #dates (dt) values ('1/2/2001')
insert into #dates (dt) values ('1/3/2001')
insert into #dates (dt) values ('1/4/2001')
insert into #dates (dt) values ('1/5/2001')
select
dt, day(dt), dateadd(dd,1,dt)
from
#dates
where
day(dt) between 1 and 4
union all
select
dt, day(dt), dateadd(dd,3,dt)
from
#dates
where
day(dt) = 5
drop table #dates