क्या यह किसी भी वर्ष के लिए है? मैं मानता हूं कि आप चालू वर्ष के लिए शेड्यूल चाहते हैं। यदि आप भविष्य के वर्ष को चाहते हैं तो आप भविष्य की तारीख निर्दिष्ट करने के लिए हमेशा DECLARE @now
बदल सकते हैं।
"एक बार 2 सप्ताह में" (एक गैर लीप वर्ष में फरवरी के लिए छोड़कर) मासिक बाल्टी में अच्छी तरह से फिट नहीं करता है (आमतौर पर के रूप में "द्वि-साप्ताहिक" कहा जाता है)। क्या इसे संभवतः "महीने में दो बार" में बदला जाना चाहिए?
इसके अलावा, आवृत्ति तालिका में गुणांक को स्टोर क्यों नहीं करते, "PerMonth" नामक कॉलम जोड़ते हैं? तो फिर तुम केवल दैनिक और त्रैमासिक मामलों से निपटने के लिए (और यह एक मनमाना विकल्प है कि इस जनवरी, अप्रैल में केवल क्या होगा, और इतने पर है?)।
USE tempdb;
GO
CREATE TABLE dbo.Frequency
(
Id INT PRIMARY KEY,
Frequency VARCHAR(32),
PerMonth TINYINT
);
CREATE TABLE dbo.EmailBlast
(
Id INT,
FrequencyId INT,
UserId INT
);
और यह नमूना डेटा:
INSERT dbo.Frequency(Id, Frequency, PerMonth)
SELECT 1, 'Daily', NULL
UNION ALL SELECT 2, 'Weekly', 4
UNION ALL SELECT 3, 'Monthly', 1
UNION ALL SELECT 4, 'Quarterly', NULL
UNION ALL SELECT 5, 'Twice a month', 2;
INSERT dbo.EmailBlast(Id, FrequencyId, UserId)
SELECT 1, 5, 1
UNION ALL SELECT 2, 2, 1
UNION ALL SELECT 3, 4, 1;
हम कर सकते हैं
यह मानते हुए कि इस में से कुछ यहाँ लचीला है, मैं, क्या सुझाव है कि तालिका स्कीमा को यह बहुत मामूली परिवर्तन मानते हुए है इसे एक बहुत ही जटिल क्वेरी का उपयोग करके पूरा करें (लेकिन हमें उन महीनों की संख्या को हार्ड-कोड नहीं करना है):
DECLARE @now DATE = CURRENT_TIMESTAMP;
DECLARE @Jan1 DATE = DATEADD(MONTH, 1-MONTH(@now), DATEADD(DAY, 1-DAY(@now), @now));
WITH n(m) AS
(
SELECT TOP 12 m = number
FROM master.dbo.spt_values
WHERE number > 0 GROUP BY number
),
months(MNum, MName, StartDate, NumDays) AS
( SELECT m, mn = CONVERT(CHAR(3), DATENAME(MONTH, DATEADD(MONTH, m-1, @Jan1))),
DATEADD(MONTH, m-1, @Jan1),
DATEDIFF(DAY, DATEADD(MONTH, m-1, @Jan1), DATEADD(MONTH, m, @Jan1))
FROM n
),
grp AS
(
SELECT UserId, MName, c = SUM (
CASE x.Id WHEN 1 THEN NumDays
WHEN 4 THEN CASE WHEN MNum % 3 = 1 THEN 1 ELSE 0 END
ELSE x.PerMonth END)
FROM months CROSS JOIN (SELECT e.UserId, f.*
FROM EmailBlast AS e
INNER JOIN Frequency AS f
ON e.FrequencyId = f.Id) AS x
GROUP BY UserId, MName
),
cumulative(UserId, total) AS
(
SELECT UserId, SUM(c)
FROM grp GROUP BY UserID
),
pivoted AS
(
SELECT * FROM (SELECT UserId, c, MName FROM grp) AS grp
PIVOT(MAX(c) FOR MName IN (
[Jan],[Feb],[Mar],[Apr],[May],[Jun],[Jul],[Aug],[Sep],[Oct],[Nov],[Dec])
) AS pvt
)
SELECT p.*, c.total
FROM pivoted AS p
LEFT OUTER JOIN cumulative AS c
ON p.UserId = c.UserId;
परिणाम:
UserId Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec total
1 7 6 6 7 6 6 7 6 6 7 6 6 76
साफ अप:
DROP TABLE dbo.EmailBlast, dbo.Frequency;
GO
वास्तव में स्कीमा परिवर्तन मैं वास्तव में आप ज्यादा नहीं खरीदती सुझाव दिया, यह सिर्फ आप grp
CTE के अंदर दो अतिरिक्त CASE
शाखाओं की बचत होती है। मूंगफली, कुल मिलाकर।
क्या आप वाकई सही डेटा प्रदर्शित कर रहे हैं? सिर्फ इसलिए कि किसी निश्चित समय से बाहर जाने के लिए कुछ कॉन्फ़िगर किया गया है, इसका मतलब यह नहीं है कि यह किया गया है। मैं गलत कर सकता हूं कि आप क्या कर रहे हैं लेकिन मुझे लगता है कि प्रति माह किए गए विस्फोटों की वास्तविक संख्या को गिनना बेहतर होगा ... – NotMe
आपका आखिरी मामला नहीं होना चाहिए जब फ्रीक्वेंसी आईडी = 5 फिर 2 –
@ क्रिस, ये विस्फोट वास्तव में समय सारिणी हैं। डिस्प्ले दिखाता है कि वर्तमान आवृत्तियों के साथ ईमेल कितनी बार भेजा जाएगा। मेरा विश्वास करो, यह एक आवश्यकता है इसलिए यह देखने का कोई मतलब नहीं कि क्या यह सही है या गलत है। वहाँ किया गया था कि। –