تحويل اسم يوم إلى تمثيلها الصحيح
-
23-08-2019 - |
سؤال
في SQL Server، يمكنك استخدام وظيفة Datename للحصول على يوم الأسبوع كسلسلة
declare @date datetime
set @date = '12/16/08'
select datename(dw, @date)
الذي يعود "الثلاثاء"
ويمكنك استخدام وظيفة DeatePart للحصول على يوم الأسبوع كعدد صحيح
declare @date datetime
set @date = '12/16/08'
select datepart(dw, @date)
الذي يعود 3.
ولكن قل لدي varchar التي تحتوي على السلسلة "الثلاثاء" وأريد تحويلها إلى تمثيلها الصحيح 3. بالتأكيد، يمكنني أن أكتب التحويل دون الكثير من المتاعب، لكنني أفضل استخدام وظيفة مدمجة وبعد هل هذه الوظيفة موجودة؟
المحلول
بدلا من كتابة وظيفة، يجب عليك إنشاء أيام من طاولة الأسبوع مع الوصف والقيمة الرقمية. ثم يمكنك ببساطة الانضمام إلى الجدول للحصول على الرقمية.
وإذا كان لديك أيام تخزين طرق متعددة (من المرجح في نظام على الطابع)، فيمكنك وضع جميع المتغيرات في الجدول، لذلك الثلاثاء، الثلاثاء، يوم الثلاثاء، كلها خريطة كاملة لنفس عدد صحيح.
نصائح أخرى
لسوء الحظ، لا يوجد وظيفة مدمجة، ولكن يمكنك إنشاء نفسها مثل هذا:
CREATE FUNCTION dbo.WeekDay(@DayOfWeek Varchar(9))
RETURNS INT
AS
BEGIN
DECLARE @iDayofWeek INT
SELECT @iDayofWeek = CASE @DayOfWeek
WHEN 'Sunday' THEN 1
WHEN 'Monday' THEN 2
WHEN 'Tuesday' THEN 3
WHEN 'Wednesday' THEN 4
WHEN 'Thursday' THEN 5
WHEN 'Friday' THEN 6
WHEN 'Saturday' THEN 7
END
RETURN (@iDayofWeek)
END
GO
حسنا بعد 6 سنوات وعدة إصدار من SQL Server ولكن لا توجد وظيفة مدمجة للقيام بذلك (بقدر ما أعرف). ليس متأكدا مما اذا SQL-SERVER-2014 سوف شيء للقيام بذلك.
أخذت نهجا مماثلا ل RussBraDBerry IF
صياغات.
CREATE FUNCTION dbo.WeekDayInt (@DayOfWeekName VARCHAR(10))
RETURNS INT
AS
BEGIN
DECLARE @DayWeekNumber INT
IF @DayOfWeekName = 'Sunday' SET @DayWeekNumber = 1
IF @DayOfWeekName = 'Monday' SET @DayWeekNumber = 2
IF @DayOfWeekName = 'Tuesday' SET @DayWeekNumber = 3
IF @DayOfWeekName = 'Wednesday' SET @DayWeekNumber = 4
IF @DayOfWeekName = 'Thursday' SET @DayWeekNumber = 5
IF @DayOfWeekName = 'Friday' SET @DayWeekNumber = 6
IF @DayOfWeekName = 'Saturday' SET @DayWeekNumber = 7;
RETURN (@DayWeekNumber)
END
أو كبديل يمكن القيام به بهذه الطريقة، والتي يمكن أن تكون أسرع قليلا لأنه سيعود القيمة بمجرد مواجهة التطابق وليس محاولة تقييم القيم الأخرى.
CREATE FUNCTION dbo.WeekDayInt (@DayOfWeekName VARCHAR(10))
RETURNS INT
AS
BEGIN
IF @DayOfWeekName = 'Sunday' RETURN 1
IF @DayOfWeekName = 'Monday' RETURN 2
IF @DayOfWeekName = 'Tuesday' RETURN 3
IF @DayOfWeekName = 'Wednesday' RETURN 4
IF @DayOfWeekName = 'Thursday' RETURN 5
IF @DayOfWeekName = 'Friday' RETURN 6
IF @DayOfWeekName = 'Saturday' RETURN 7;
RETURN 0;
END
فيما يلي بديل قذر يمكنني استخدامه إذا لم أكن تشغيله على مجموعة بيانات ضخمة.
Select CHARINDEX(SUBSTRING('Thursday',1,3), 'MONTUEWEDTHUFRISATSUN') / 3 + 1
فقط استبدل يوم الخميس في يوم من اختيارك أو متغير.
كيف تعمل: السلسلة الفرعية ("الخميس"، 1،3) تنشئ أساسا، ثم اكتشف Charindex موقف الخميس في السلسلة التي تبلغ 10. نقسم بعد ذلك 10 بطول كلماتنا اليومية التي تبلغ 3 منها 3، ولأنني أريد
يوم الاثنين يساوي 1 يوم الثلاثاء على قدم المساواة يوم الأربعاء إلى تساوي 3 يوم الخميس على قدم المساواة في 4
أضف 1 إلى النهاية
لذلك النتيجة هي 4.
نأمل أن يساعد شخص ما، لكنني أوافق على الأرجح ليس أفضل حل.
ملاحظة: يمكنك أيضا طلب نتيجة تعيين حسب رقم اليوم باستخدامه مثل ذلك:
SELECT ID,DayNamesColumn from mytable ORDER BY CHARINDEX(SUBSTRING(DayNamesColumn ,1,3), 'MONTUEWEDTHUFRISATSUN') / 3 + 1
يمكنك استخدام تحديد ما يلي للحصول على ترتيبي تاريخ الأسبوع ISO 2017-12-15
فيما يتعلق (على سبيل المثال بغض النظر عن) الإعداد الحالي من DateFirst الذي يحدد اليوم الأول من الأسبوع. على سبيل المثال تعيين dateFirst = 1 ليوم الاثنين.
select
w.weekday_id_iso8601,
w.weekday_id_datepart,
w.weekday_name
from (
values
(7, 'Monday'),
(8, 'Tuesday'),
(9, 'Wednesday'),
(10, 'Thursday'),
(11, 'Friday'),
(12, 'Saturday'),
(13, 'Sunday'))
t(weekday_id, weekday_name)
cross apply (
select
t.weekday_id - 6 weekday_id_iso8601,
(t.weekday_id - @@datefirst + 1) % 7 + 1 weekday_id_datepart,
t.weekday_name
) w
where w.weekday_id_datepart = datepart(weekday, '2017-12-15')
لا أتفق مع الإجابة حول إضافة جدول بحث، لأنه في هذه الحالة، تكون القيم محدودة ولن تتغير أبدا. سوف ينضم جدول البحث فقط إضافة تكلفة.
IMHO؛ نظرا لأن لديك قيم محدودة، أود فقط استخدام بيان الحالة في آرائي. انها ليست جميلة، ولكن من المحتمل أن تكون أسرع طريقة للقيام بذلك.
قد لا يخدم هذا غرضا عمليا، لكنني اعتقدت أنني سأكون من أجل المتعة فقط. :) الأعمال التالية.
تذكر أنه عند استخدام DeatePart أو Datename أن قيمة @ dateFirst مهمة ويمكن أن تغير نتائجك. ابحث عن ضبط DateFirst في التعليمات عبر الإنترنت.
DECLARE
@date_name AS VARCHAR(20)
SET @date_name = 'Monday'
SELECT
DATEPART(dw, my_date)
FROM
(
SELECT CAST('1900-01-01' AS DATETIME) AS my_date UNION
SELECT CAST('1900-01-02' AS DATETIME) AS my_date UNION
SELECT CAST('1900-01-03' AS DATETIME) AS my_date UNION
SELECT CAST('1900-01-04' AS DATETIME) AS my_date UNION
SELECT CAST('1900-01-05' AS DATETIME) AS my_date UNION
SELECT CAST('1900-01-06' AS DATETIME) AS my_date UNION
SELECT CAST('1900-01-07' AS DATETIME) AS my_date
) AS My_Dates
WHERE
DATENAME(dw, my_date) = @date_name
أين DayID
هي قيمة عدد صحيح 1 من خلال 7.
أضف Dayid إلى بعض التاريخ الأساسي مثل 1899-12-31. (إذا كان الأحد هو اليوم الأول من الأسبوع، استخدم التاريخ الأولي لعام 1899-12-30)
1900-01-01 كان الاثنين، 1900-01-02 كان يوم الثلاثاء، وهلم جرا.
هكذا :
select DayID,
datename( weekday, dateadd( day, DayID, '18991231' ) )
في SQL 2014، يمكنك استخدام:
حدد DeatePart (DW، GetDate ()) هذا سيعود يوما من الأسبوع كعدد صحيح.