मुझे दो प्रणालियों के बीच डेटा परिवर्तित करने की आवश्यकता है।
पहले सिस्टम तारीखों की एक सादे सूची के रूप में शेड्यूल करता है। अनुसूची में शामिल प्रत्येक तिथि एक पंक्ति है। तिथियों के क्रम में कई अंतराल हो सकते हैं (सप्ताहांत, सार्वजनिक अवकाश और लंबे समय तक रुकने के लिए, सप्ताह के कुछ दिनों को अनुसूची से बाहर रखा जा सकता है)। कोई अंतराल नहीं हो सकता है, यहां तक कि सप्ताहांत भी शामिल किया जा सकता है। शेड्यूल 2 साल तक लंबा हो सकता है। आमतौर पर यह कुछ सप्ताह लंबा होता है।
यहाँ एक अनुसूची का एक सरल उदाहरण है जो सप्ताहांत को छोड़कर दो सप्ताह तक फैला है (नीचे स्क्रिप्ट में अधिक जटिल उदाहरण हैं):
+----+------------+------------+---------+--------+
| ID | ContractID | dt | dowChar | dowInt |
+----+------------+------------+---------+--------+
| 10 | 1 | 2016-05-02 | Mon | 2 |
| 11 | 1 | 2016-05-03 | Tue | 3 |
| 12 | 1 | 2016-05-04 | Wed | 4 |
| 13 | 1 | 2016-05-05 | Thu | 5 |
| 14 | 1 | 2016-05-06 | Fri | 6 |
| 15 | 1 | 2016-05-09 | Mon | 2 |
| 16 | 1 | 2016-05-10 | Tue | 3 |
| 17 | 1 | 2016-05-11 | Wed | 4 |
| 18 | 1 | 2016-05-12 | Thu | 5 |
| 19 | 1 | 2016-05-13 | Fri | 6 |
+----+------------+------------+---------+--------+
ID
अद्वितीय है, लेकिन यह जरूरी नहीं कि अनुक्रमिक (यह प्राथमिक कुंजी है)। प्रत्येक अनुबंध के भीतर तिथियां अद्वितीय हैं (पर अद्वितीय सूचकांक है (ContractID, dt)
)।
दूसरा सिस्टम शेड्यूल के सप्ताह के दिनों की सूची के साथ अंतराल के रूप में स्टोर करता है। प्रत्येक अंतराल को इसकी शुरुआत और अंतिम तिथियों (समावेशी) और सप्ताह के दिनों की सूची द्वारा परिभाषित किया जाता है जो अनुसूची में शामिल हैं। इस प्रारूप में आप कुशलतापूर्वक दोहराव वाले साप्ताहिक पैटर्न को परिभाषित कर सकते हैं, जैसे मोन-वेस, लेकिन यह एक दर्द बन जाता है जब एक पैटर्न बाधित होता है, उदाहरण के लिए सार्वजनिक अवकाश।
यहां बताया गया है कि ऊपर का सरल उदाहरण कैसा दिखेगा:
+------------+------------+------------+----------+----------------------+
| ContractID | StartDT | EndDT | DayCount | WeekDays |
+------------+------------+------------+----------+----------------------+
| 1 | 2016-05-02 | 2016-05-13 | 10 | Mon,Tue,Wed,Thu,Fri, |
+------------+------------+------------+----------+----------------------+
[StartDT;EndDT]
अंतराल जो एक ही अनुबंध के हैं, ओवरलैप नहीं होना चाहिए।
मुझे पहली प्रणाली से डेटा को दूसरी प्रणाली द्वारा उपयोग किए जाने वाले प्रारूप में बदलने की आवश्यकता है। फिलहाल मैं इसे दिए गए कॉन्ट्रैक्ट के लिए C # में क्लाइंट की ओर से हल कर रहा हूं, लेकिन मैं इसे सर्वर पर बल्क प्रोसेसिंग और एक्सपोर्ट / इंपोर्ट के लिए सर्वर साइड में T-SQL में करना चाहूंगा। सबसे अधिक संभावना है, यह CLR UDF का उपयोग करके किया जा सकता है, लेकिन इस स्तर पर मैं SQLCLR का उपयोग नहीं कर सकता।
यहां चुनौती अंतराल की सूची को यथासंभव छोटा और मानव-अनुकूल बनाना है।
उदाहरण के लिए, यह अनुसूची:
+-----+------------+------------+---------+--------+
| ID | ContractID | dt | dowChar | dowInt |
+-----+------------+------------+---------+--------+
| 223 | 2 | 2016-05-05 | Thu | 5 |
| 224 | 2 | 2016-05-06 | Fri | 6 |
| 225 | 2 | 2016-05-09 | Mon | 2 |
| 226 | 2 | 2016-05-10 | Tue | 3 |
| 227 | 2 | 2016-05-11 | Wed | 4 |
| 228 | 2 | 2016-05-12 | Thu | 5 |
| 229 | 2 | 2016-05-13 | Fri | 6 |
| 230 | 2 | 2016-05-16 | Mon | 2 |
| 231 | 2 | 2016-05-17 | Tue | 3 |
+-----+------------+------------+---------+--------+
यह बनना चाहिए:
+------------+------------+------------+----------+----------------------+
| ContractID | StartDT | EndDT | DayCount | WeekDays |
+------------+------------+------------+----------+----------------------+
| 2 | 2016-05-05 | 2016-05-17 | 9 | Mon,Tue,Wed,Thu,Fri, |
+------------+------------+------------+----------+----------------------+
,यह नहीं:
+------------+------------+------------+----------+----------------------+
| ContractID | StartDT | EndDT | DayCount | WeekDays |
+------------+------------+------------+----------+----------------------+
| 2 | 2016-05-05 | 2016-05-06 | 2 | Thu,Fri, |
| 2 | 2016-05-09 | 2016-05-13 | 5 | Mon,Tue,Wed,Thu,Fri, |
| 2 | 2016-05-16 | 2016-05-17 | 2 | Mon,Tue, |
+------------+------------+------------+----------+----------------------+
मैंने gaps-and-islands
इस समस्या के लिए एक दृष्टिकोण लागू करने की कोशिश की । मैंने इसे दो पास में करने की कोशिश की। पहले पास में मुझे लगातार सरल दिनों के द्वीप मिलते हैं, अर्थात द्वीप का अंत दिनों के अनुक्रम में कोई अंतराल है, चाहे वह सप्ताहांत हो, सार्वजनिक अवकाश हो या कुछ और। प्रत्येक ऐसे पाए गए द्वीप के लिए, मैं विशिष्ट अल्पविराम से अलग सूची बनाता हूं WeekDays
। दूसरे पास में I समूह ने सप्ताह संख्याओं के अनुक्रम में अंतर को देखते हुए या में बदलाव को देखते हुए द्वीपों को और अधिक पाया WeekDays
।
इस दृष्टिकोण के साथ प्रत्येक आंशिक सप्ताह एक अतिरिक्त अंतराल के रूप में समाप्त होता है जैसा कि ऊपर दिखाया गया है, क्योंकि भले ही सप्ताह संख्या लगातार हो, WeekDays
परिवर्तन। इसके अलावा, एक सप्ताह के भीतर नियमित अंतराल हो सकता है ( ContractID=3
नमूना डेटा में देखें , जिसमें केवल डेटा है Mon,Wed,Fri,
) और यह दृष्टिकोण इस तरह के शेड्यूल में प्रत्येक दिन के लिए अलग अंतराल उत्पन्न करेगा। उज्ज्वल पक्ष पर, यह एक अंतराल उत्पन्न करता है यदि शेड्यूल में कोई अंतराल नहीं है ( ContractID=7
नमूना डेटा जिसमें सप्ताहांत शामिल हैं) देखें और उस स्थिति में यह कोई फर्क नहीं पड़ता कि शुरुआत या अंत सप्ताह आंशिक है।
कृपया इसके बाद की स्क्रिप्ट में बेहतर उदाहरण देखने के लिए नीचे दिए गए अन्य उदाहरण देखें। आप देख सकते हैं कि अक्सर सप्ताहांत को बाहर रखा जाता है, लेकिन सप्ताह के किसी भी अन्य दिन को भी बाहर रखा जा सकता है। उदाहरण में केवल 3 Mon
, Wed
और Fri
अनुसूची का हिस्सा हैं। इसके अलावा, सप्ताहांत को शामिल किया जा सकता है, उदाहरण के लिए 7. समाधान सप्ताह के सभी दिनों को समान रूप से व्यवहार करना चाहिए। सप्ताह के किसी भी दिन को शेड्यूल से शामिल या बाहर रखा जा सकता है।
यह सत्यापित करने के लिए कि अंतराल की जनरेट की गई सूची दिए गए शेड्यूल का सही वर्णन करती है, आप निम्न छद्म कोड का उपयोग कर सकते हैं:
- सभी अंतराल के माध्यम से पाश
- प्रारंभ और समाप्ति तिथियों (सम्मिलित) के बीच सभी कैलेंडर तिथियों के माध्यम से प्रत्येक अंतराल लूप के लिए।
- प्रत्येक तिथि की जाँच करें कि क्या सप्ताह का उसका दिन सूचीबद्ध है
WeekDays
। यदि हाँ, तो यह तिथि अनुसूची में शामिल है।
उम्मीद है, यह स्पष्ट करता है कि किन मामलों में एक नया अंतराल बनाया जाना चाहिए। उदाहरण 4 और 5 में एक सोमवार ( 2016-05-09
) अनुसूची के बीच से हटा दिया जाता है और इस तरह के शेड्यूल को एक एकल अंतराल द्वारा प्रतिनिधित्व नहीं किया जा सकता है। उदाहरण 6 में अनुसूची में एक लंबा अंतराल है, इसलिए दो अंतराल की आवश्यकता है।
अंतराल अनुसूची में साप्ताहिक पैटर्न का प्रतिनिधित्व करते हैं और जब एक पैटर्न बाधित / बदल जाता है तो नया अंतराल जोड़ना पड़ता है। उदाहरण के लिए 11 पहले तीन हफ्तों में एक पैटर्न होता है Tue
, फिर यह पैटर्न बदल जाता है Thu
। परिणामस्वरूप हमें इस तरह के कार्यक्रम का वर्णन करने के लिए दो अंतराल की आवश्यकता होती है।
मैं इस समय SQL सर्वर 2008 का उपयोग कर रहा हूं, इसलिए इस संस्करण में समाधान काम करना चाहिए। यदि SQL Server 2008 के समाधान को बाद के संस्करणों से सुविधाओं का उपयोग करके सरल / बेहतर बनाया जा सकता है, तो यह एक बोनस है, कृपया इसे भी दिखाएं।
मेरे पास एक Calendar
तालिका (तारीखों की सूची) और Numbers
तालिका (1 से शुरू होने वाले पूर्णांक संख्या की सूची) है, इसलिए यदि आवश्यक हो, तो उनका उपयोग करना ठीक है। अस्थायी तालिकाएँ बनाना भी ठीक है और कई क्वेरीज़ हैं जो डेटा को कई चरणों में प्रोसेस करती हैं। एक एल्गोरिथ्म में चरणों की संख्या तय की जानी है, हालांकि, कर्सर और स्पष्ट WHILE
लूप ठीक नहीं हैं।
नमूना डेटा और अपेक्षित परिणामों के लिए स्क्रिप्ट
-- @Src is sample data
-- @Dst is expected result
DECLARE @Src TABLE (ID int PRIMARY KEY, ContractID int, dt date, dowChar char(3), dowInt int);
INSERT INTO @Src (ID, ContractID, dt, dowChar, dowInt) VALUES
-- simple two weeks (without weekend)
(110, 1, '2016-05-02', 'Mon', 2),
(111, 1, '2016-05-03', 'Tue', 3),
(112, 1, '2016-05-04', 'Wed', 4),
(113, 1, '2016-05-05', 'Thu', 5),
(114, 1, '2016-05-06', 'Fri', 6),
(115, 1, '2016-05-09', 'Mon', 2),
(116, 1, '2016-05-10', 'Tue', 3),
(117, 1, '2016-05-11', 'Wed', 4),
(118, 1, '2016-05-12', 'Thu', 5),
(119, 1, '2016-05-13', 'Fri', 6),
-- a partial end of the week, the whole week, partial start of the week (without weekends)
(223, 2, '2016-05-05', 'Thu', 5),
(224, 2, '2016-05-06', 'Fri', 6),
(225, 2, '2016-05-09', 'Mon', 2),
(226, 2, '2016-05-10', 'Tue', 3),
(227, 2, '2016-05-11', 'Wed', 4),
(228, 2, '2016-05-12', 'Thu', 5),
(229, 2, '2016-05-13', 'Fri', 6),
(230, 2, '2016-05-16', 'Mon', 2),
(231, 2, '2016-05-17', 'Tue', 3),
-- only Mon, Wed, Fri are included across two weeks plus partial third week
(310, 3, '2016-05-02', 'Mon', 2),
(311, 3, '2016-05-04', 'Wed', 4),
(314, 3, '2016-05-06', 'Fri', 6),
(315, 3, '2016-05-09', 'Mon', 2),
(317, 3, '2016-05-11', 'Wed', 4),
(319, 3, '2016-05-13', 'Fri', 6),
(330, 3, '2016-05-16', 'Mon', 2),
-- a whole week (without weekend), in the second week Mon is not included
(410, 4, '2016-05-02', 'Mon', 2),
(411, 4, '2016-05-03', 'Tue', 3),
(412, 4, '2016-05-04', 'Wed', 4),
(413, 4, '2016-05-05', 'Thu', 5),
(414, 4, '2016-05-06', 'Fri', 6),
(416, 4, '2016-05-10', 'Tue', 3),
(417, 4, '2016-05-11', 'Wed', 4),
(418, 4, '2016-05-12', 'Thu', 5),
(419, 4, '2016-05-13', 'Fri', 6),
-- three weeks, but without Mon in the second week (no weekends)
(510, 5, '2016-05-02', 'Mon', 2),
(511, 5, '2016-05-03', 'Tue', 3),
(512, 5, '2016-05-04', 'Wed', 4),
(513, 5, '2016-05-05', 'Thu', 5),
(514, 5, '2016-05-06', 'Fri', 6),
(516, 5, '2016-05-10', 'Tue', 3),
(517, 5, '2016-05-11', 'Wed', 4),
(518, 5, '2016-05-12', 'Thu', 5),
(519, 5, '2016-05-13', 'Fri', 6),
(520, 5, '2016-05-16', 'Mon', 2),
(521, 5, '2016-05-17', 'Tue', 3),
(522, 5, '2016-05-18', 'Wed', 4),
(523, 5, '2016-05-19', 'Thu', 5),
(524, 5, '2016-05-20', 'Fri', 6),
-- long gap between two intervals
(623, 6, '2016-05-05', 'Thu', 5),
(624, 6, '2016-05-06', 'Fri', 6),
(625, 6, '2016-05-09', 'Mon', 2),
(626, 6, '2016-05-10', 'Tue', 3),
(627, 6, '2016-05-11', 'Wed', 4),
(628, 6, '2016-05-12', 'Thu', 5),
(629, 6, '2016-05-13', 'Fri', 6),
(630, 6, '2016-05-16', 'Mon', 2),
(631, 6, '2016-05-17', 'Tue', 3),
(645, 6, '2016-06-06', 'Mon', 2),
(646, 6, '2016-06-07', 'Tue', 3),
(647, 6, '2016-06-08', 'Wed', 4),
(648, 6, '2016-06-09', 'Thu', 5),
(649, 6, '2016-06-10', 'Fri', 6),
(655, 6, '2016-06-13', 'Mon', 2),
(656, 6, '2016-06-14', 'Tue', 3),
(657, 6, '2016-06-15', 'Wed', 4),
(658, 6, '2016-06-16', 'Thu', 5),
(659, 6, '2016-06-17', 'Fri', 6),
-- two weeks, no gaps between days at all, even weekends are included
(710, 7, '2016-05-02', 'Mon', 2),
(711, 7, '2016-05-03', 'Tue', 3),
(712, 7, '2016-05-04', 'Wed', 4),
(713, 7, '2016-05-05', 'Thu', 5),
(714, 7, '2016-05-06', 'Fri', 6),
(715, 7, '2016-05-07', 'Sat', 7),
(716, 7, '2016-05-08', 'Sun', 1),
(725, 7, '2016-05-09', 'Mon', 2),
(726, 7, '2016-05-10', 'Tue', 3),
(727, 7, '2016-05-11', 'Wed', 4),
(728, 7, '2016-05-12', 'Thu', 5),
(729, 7, '2016-05-13', 'Fri', 6),
-- no gaps between days at all, even weekends are included, with partial weeks
(805, 8, '2016-04-30', 'Sat', 7),
(806, 8, '2016-05-01', 'Sun', 1),
(810, 8, '2016-05-02', 'Mon', 2),
(811, 8, '2016-05-03', 'Tue', 3),
(812, 8, '2016-05-04', 'Wed', 4),
(813, 8, '2016-05-05', 'Thu', 5),
(814, 8, '2016-05-06', 'Fri', 6),
(815, 8, '2016-05-07', 'Sat', 7),
(816, 8, '2016-05-08', 'Sun', 1),
(825, 8, '2016-05-09', 'Mon', 2),
(826, 8, '2016-05-10', 'Tue', 3),
(827, 8, '2016-05-11', 'Wed', 4),
(828, 8, '2016-05-12', 'Thu', 5),
(829, 8, '2016-05-13', 'Fri', 6),
(830, 8, '2016-05-14', 'Sat', 7),
-- only Mon-Wed included, two weeks plus partial third week
(910, 9, '2016-05-02', 'Mon', 2),
(911, 9, '2016-05-03', 'Tue', 3),
(912, 9, '2016-05-04', 'Wed', 4),
(915, 9, '2016-05-09', 'Mon', 2),
(916, 9, '2016-05-10', 'Tue', 3),
(917, 9, '2016-05-11', 'Wed', 4),
(930, 9, '2016-05-16', 'Mon', 2),
(931, 9, '2016-05-17', 'Tue', 3),
-- only Thu-Sun included, three weeks
(1013,10,'2016-05-05', 'Thu', 5),
(1014,10,'2016-05-06', 'Fri', 6),
(1015,10,'2016-05-07', 'Sat', 7),
(1016,10,'2016-05-08', 'Sun', 1),
(1018,10,'2016-05-12', 'Thu', 5),
(1019,10,'2016-05-13', 'Fri', 6),
(1020,10,'2016-05-14', 'Sat', 7),
(1021,10,'2016-05-15', 'Sun', 1),
(1023,10,'2016-05-19', 'Thu', 5),
(1024,10,'2016-05-20', 'Fri', 6),
(1025,10,'2016-05-21', 'Sat', 7),
(1026,10,'2016-05-22', 'Sun', 1),
-- only Tue for first three weeks, then only Thu for the next three weeks
(1111,11,'2016-05-03', 'Tue', 3),
(1116,11,'2016-05-10', 'Tue', 3),
(1131,11,'2016-05-17', 'Tue', 3),
(1123,11,'2016-05-19', 'Thu', 5),
(1124,11,'2016-05-26', 'Thu', 5),
(1125,11,'2016-06-02', 'Thu', 5),
-- one week, then one week gap, then one week
(1210,12,'2016-05-02', 'Mon', 2),
(1211,12,'2016-05-03', 'Tue', 3),
(1212,12,'2016-05-04', 'Wed', 4),
(1213,12,'2016-05-05', 'Thu', 5),
(1214,12,'2016-05-06', 'Fri', 6),
(1215,12,'2016-05-16', 'Mon', 2),
(1216,12,'2016-05-17', 'Tue', 3),
(1217,12,'2016-05-18', 'Wed', 4),
(1218,12,'2016-05-19', 'Thu', 5),
(1219,12,'2016-05-20', 'Fri', 6);
SELECT ID, ContractID, dt, dowChar, dowInt
FROM @Src
ORDER BY ContractID, dt;
DECLARE @Dst TABLE (ContractID int, StartDT date, EndDT date, DayCount int, WeekDays varchar(255));
INSERT INTO @Dst (ContractID, StartDT, EndDT, DayCount, WeekDays) VALUES
(1, '2016-05-02', '2016-05-13', 10, 'Mon,Tue,Wed,Thu,Fri,'),
(2, '2016-05-05', '2016-05-17', 9, 'Mon,Tue,Wed,Thu,Fri,'),
(3, '2016-05-02', '2016-05-16', 7, 'Mon,Wed,Fri,'),
(4, '2016-05-02', '2016-05-06', 5, 'Mon,Tue,Wed,Thu,Fri,'),
(4, '2016-05-10', '2016-05-13', 4, 'Tue,Wed,Thu,Fri,'),
(5, '2016-05-02', '2016-05-06', 5, 'Mon,Tue,Wed,Thu,Fri,'),
(5, '2016-05-10', '2016-05-20', 9, 'Mon,Tue,Wed,Thu,Fri,'),
(6, '2016-05-05', '2016-05-17', 9, 'Mon,Tue,Wed,Thu,Fri,'),
(6, '2016-06-06', '2016-06-17', 10, 'Mon,Tue,Wed,Thu,Fri,'),
(7, '2016-05-02', '2016-05-13', 12, 'Sun,Mon,Tue,Wed,Thu,Fri,Sat,'),
(8, '2016-04-30', '2016-05-14', 15, 'Sun,Mon,Tue,Wed,Thu,Fri,Sat,'),
(9, '2016-05-02', '2016-05-17', 8, 'Mon,Tue,Wed,'),
(10,'2016-05-05', '2016-05-22', 12, 'Sun,Thu,Fri,Sat,'),
(11,'2016-05-03', '2016-05-17', 3, 'Tue,'),
(11,'2016-05-19', '2016-06-02', 3, 'Thu,'),
(12,'2016-05-02', '2016-05-06', 5, 'Mon,Tue,Wed,Thu,Fri,'),
(12,'2016-05-16', '2016-05-20', 5, 'Mon,Tue,Wed,Thu,Fri,');
SELECT ContractID, StartDT, EndDT, DayCount, WeekDays
FROM @Dst
ORDER BY ContractID, StartDT;
उत्तरों की तुलना
असली तालिका @Src
में अलग-अलग 403,555
पंक्तियाँ हैं । सभी उत्तर सही परिणाम देते हैं (कम से कम मेरे डेटा के लिए) और उनमें से सभी यथोचित रूप से तेज़ हैं, लेकिन वे इष्टतमता में भिन्न हैं। कम अंतराल उत्पन्न, बेहतर। मैंने सिर्फ जिज्ञासा के लिए रन टाइम को शामिल किया। मुख्य फोकस सही और इष्टतम परिणाम है, न कि गति (जब तक कि बहुत लंबा न हो जाए - मैंने 10 मिनट के बाद जिग्गी क्रूएल्टीफ्री ज़ेतिगेस्टर द्वारा गैर-पुनरावर्ती क्वेरी को रोक दिया)।15,857
ContractIDs
+--------------------------------------------------------+-----------+---------+
| Answer | Intervals | Seconds |
+--------------------------------------------------------+-----------+---------+
| Ziggy Crueltyfree Zeitgeister | 25751 | 7.88 |
| While loop | | |
| | | |
| Ziggy Crueltyfree Zeitgeister | 25751 | 8.27 |
| Recursive | | |
| | | |
| Michael Green | 25751 | 22.63 |
| Recursive | | |
| | | |
| Geoff Patterson | 26670 | 4.79 |
| Weekly gaps-and-islands with merging of partial weeks | | |
| | | |
| Vladimir Baranov | 34560 | 4.03 |
| Daily, then weekly gaps-and-islands | | |
| | | |
| Mikael Eriksson | 35840 | 0.65 |
| Weekly gaps-and-islands | | |
+--------------------------------------------------------+-----------+---------+
| Vladimir Baranov | 25751 | 121.51 |
| Cursor | | |
+--------------------------------------------------------+-----------+---------+
@Dst
) होना आवश्यक है। शेड्यूल के पहले दो सप्ताह केवल हैं Tue
, इसलिए आप WeekDays=Tue,Thu,
इन हफ्तों के लिए नहीं कर सकते । शेड्यूल के अंतिम दो सप्ताह केवल हैं Thu
, इसलिए आप फिर से WeekDays=Tue,Thu,
इन हफ्तों के लिए नहीं हो सकते । इसके लिए उप-इष्टतम समाधान तीन पंक्तियाँ होंगी: केवल Tue
पहले दो सप्ताह के लिए, फिर Tue,Thu,
तीसरे सप्ताह के लिए , जिसमें दोनों हैं Tue
और Thu
फिर Thu
पिछले दो सप्ताह के लिए।
ContractID
परिवर्तन, यदि अंतराल 7 दिनों से परे चला जाता है और नए सप्ताह का दिन पहले नहीं देखा गया है, अगर निर्धारित दिनों की सूची में कोई अंतर है।
(11,'2016-05-03', '2016-05-17', 3, 'Tue,'), (11,'2016-05-19', '2016-06-02', 3, 'Thu,');
@Dst में एक पंक्ति के साथ नहीं होना चाहिएTue, Thu,
?