অনেক সময় অঞ্চলের ডেটা বিপরীতে প্রতিবেদন করার জন্য ডেটা গুদাম ডিজাইন


10

আমরা এমন একটি ডেটা গুদাম নকশা অনুকূলিত করার চেষ্টা করছি যা অনেক সময় অঞ্চলের জন্য ডেটা বিপরীতে প্রতিবেদন সমর্থন করবে। উদাহরণস্বরূপ, আমাদের কাছে একমাসের ক্রিয়াকলাপের লক্ষ লক্ষ (কয়েক মিলিয়ন সারি) একটি প্রতিবেদন থাকতে পারে যা দিনের ঘন্টা অনুসারে ক্রিয়াকলাপকে গোষ্ঠীভুক্ত দেখানো দরকার। এবং অবশ্যই দিনের সেই ঘন্টাটি প্রদত্ত সময় অঞ্চলটির জন্য "স্থানীয়" ঘন্টা হতে হবে।

যখন আমরা সবেমাত্র ইউটিসি এবং একটি স্থানীয় সময়কে সমর্থন করি তখন আমাদের একটি নকশা তৈরি হয়েছিল well ইউটিসি এবং স্থানীয় সময়ের জন্য তারিখ এবং সময় মাত্রার মানক নকশা, ফ্যাক্ট টেবিলগুলিতে আইডি। তবে, যদি আমাদের 100+ টাইম জোনের জন্য রিপোর্টিং সমর্থন করতে হয় তবে এই পদ্ধতির স্কেল হবে বলে মনে হচ্ছে না।

আমাদের ফ্যাক্ট টেবিলগুলি খুব প্রশস্ত হবে। এছাড়াও, এসকিউএলে সিন্ট্যাক্স ইস্যুটি সমাধান করতে হবে যা নির্দিষ্ট করে কোন রিপোর্টে গ্রুপিংয়ের জন্য কোন তারিখ এবং সময় আইডি ব্যবহার করতে হবে তা উল্লেখ করে আমাদের এসকিউএল তে সমাধান করতে হবে। সম্ভবত খুব বড় একটি CASE বিবৃতি?

আপনি যে ইউটিসির সময়সীমাটি কভার করছেন তার দ্বারা সমস্ত ডেটা পাওয়ার জন্য আমি কিছু পরামর্শ দেখেছি, তারপরে এটিকে স্থানীয়ভাবে রূপান্তর করতে এবং সেখানে সমষ্টিগতভাবে উপস্থাপনের স্তরে ফিরে আসুন, তবে এসএসআরএসের সাথে সীমাবদ্ধ পরীক্ষার পরামর্শ দেয় যা অত্যন্ত ধীর হবে।

আমি এই বিষয়ে কিছু বইয়ের সাথেও পরামর্শ করেছি এবং সেগুলি কেবলমাত্র ইউটিসি আছে এবং প্রদর্শনীতে রূপান্তর করতে পারে বা ইউটিসি এবং একটি স্থানীয় রয়েছে বলে মনে হয়। কোন চিন্তা এবং পরামর্শ প্রশংসা করবে।

দ্রষ্টব্য: এই প্রশ্নটির অনুরূপ: ডেটা মার্ট / গুদামে টাইম অঞ্চল পরিচালনা করা , তবে আমি সেই প্রশ্নটিতে মন্তব্য করতে পারি না, তাই অনুভব করেছি যে এটি নিজের প্রশ্নের যোগ্য।

আপডেট: আমি হারুনের উত্তরটি কয়েকটি উল্লেখযোগ্য আপডেট করার পরে এবং নমুনা কোড এবং ডায়াগ্রাম পোস্ট করার পরে নির্বাচন করেছি। তার উত্তর সম্পর্কে আমার আগের মন্তব্যগুলি আর উত্তর দেবে না কারণ তারা উত্তরের মূল সম্পাদনা উল্লেখ করেছে। ওয়্যারেন্টড থাকলে আমি আবার ফিরে এসে আপডেট করার চেষ্টা করব


আমার উত্তরের প্রসঙ্গে (এবং আপডেটগুলি পরে আমি এটি পোস্ট করব), আপনার ডেটা কত পিছনে যায়? একটি মাসিক রিপোর্ট 24 ঘন্টা খণ্ডগুলির 28-31 সেট দেখায়? এটি কি সর্বদা "একটি ক্যালেন্ডার মাস" হবে বা এটি কোনও রেঞ্জ হতে পারে? নির্বাচিত সময় অঞ্চলের জন্য কোনও তারিখের কোনও ডিএসটি স্প্রিং ফরোয়ার্ড / রোল ব্যাক তারিখ হলে এটি কী দেখায়? এছাড়াও, প্রতিবেদনের ইনপুটটি ঠিক কী? আপনি কি ব্যবহারকারীর স্থানীয় সময়টিকে তাদের বর্তমান লোকেলের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে ইউটিসিতে রূপান্তর করেন, তাদের কি পছন্দ আছে, তারা নিজেই নির্বাচন করেন, বা আপনি অন্য কোনও উপায়ে সিদ্ধান্ত নিয়েছেন, বা আপনি কি কোয়েরিটি খুঁজে বের করতে চান?
অ্যারন বার্ট্র্যান্ড

আপনার প্রশ্নের উত্তর দিতে: ডেটা 2 বছর পর্যন্ত ফিরে যেতে পারে। আমাদের কিছু প্রতিবেদন আছে যা 24 ঘন্টা খণ্ডগুলির কেবলমাত্র একটি সেট এবং অন্যান্য প্রতিবেদনগুলিতে প্রতিবেদনের তারিখের সীমাতে 24 ঘন্টা খণ্ড থাকে show তারিখের পরিসীমা ব্যবহারকারীরা যা চান তা আসলেই হতে পারে। ব্যবহারকারী শুরুর এবং শেষের তারিখটি (এবং সময়) নির্বাচন করে এবং তারপরে একটি ড্রপডাউন থেকে তারা যে টাইমজোনটি চায় তা নির্বাচন করে
পিটার এম

উত্তর:


18

আমি খুব সাধারণ ক্যালেন্ডার টেবিল রেখে এটিকে সমাধান করেছি - প্রতি বছর সমর্থিত সময় অঞ্চল অনুযায়ী এক সারি থাকে , স্ট্যান্ডার্ড অফসেট এবং ডিএসটি এবং এর অফসেটের প্রারম্ভের তারিখের সময় / শেষের তারিখ সহ (যদি সেই সময় অঞ্চলটি এটি সমর্থন করে)। তারপরে একটি ইনলাইন, স্কিমা-আবদ্ধ, টেবিল-মূল্যযুক্ত ফাংশন যা উত্স সময় নেয় (অবশ্যই ইউটিসিতে) এবং অফসেট যুক্ত / বিয়োগ করে।

আপনি ডেটা বড় অংশের বিরুদ্ধে প্রতিবেদন করতে পারলে স্পষ্টতই এটি কখনও খুব ভাল সম্পাদন করতে পারে না; বিভাজনটি আপনাকে সাহায্য করবে বলে মনে হতে পারে, তবে আপনার এখনও এমন ঘটনা ঘটতে পারে যেখানে এক বছরের শেষ কয়েক ঘন্টা বা পরের বছরের প্রথম কয়েক ঘন্টা আসলে একটি নির্দিষ্ট বছরের সাথে রূপান্তরিত হওয়ার সময় অন্য বছরের সাথে সম্পর্কিত - সুতরাং আপনি কখনই সত্যিকারের পার্টিশন পেতে পারবেন না বিচ্ছিন্নতা, যখন আপনার প্রতিবেদনের সীমা 31 ডিসেম্বর বা 1 জানুয়ারী অন্তর্ভুক্ত না করে থাকে।

বেশ কয়েকটি অদ্ভুত প্রান্তের মামলাগুলি আপনার বিবেচনা করা উচিত:

  • 2014-11-02 05:30 ইউটিসি এবং 2014-11-02 06:30 ইউটিসি উভয়ই পূর্ব সময় অঞ্চলে 01:30 এএম রূপান্তর করে, উদাহরণস্বরূপ (প্রথমবারের মতো 01:30 স্থানীয়ভাবে একটি আঘাত হয়েছিল, এবং তারপরে একটিতে দ্বিতীয়বার যখন ঘড়ির কাঁটা দুটি সকাল 2:00 টা থেকে 1:00 এএম এ ফিরে এসেছিল, এবং আরও আধ ঘন্টা ব্যয় হয়েছে)। সুতরাং আপনাকে কীভাবে প্রতিবেদনের সেই ঘন্টাটি পরিচালনা করতে হবে তা সিদ্ধান্ত নিতে হবে - ইউটিসি অনুসারে, আপনি এই দুটি ঘন্টা একবার ডিএসটি পর্যবেক্ষণকারী টাইম জোনে এক ঘন্টার সাথে ম্যাপ করলে আপনি যা যা পরিমাপ করছেন তার দ্বিগুণ ট্র্যাফিক বা ভলিউম দেখতে হবে। এটি ইভেন্টগুলির ক্রম সহ মজাদার গেমগুলি খেলতেও পারে, যেহেতু যুক্তিযুক্তভাবে অন্য কিছু প্রদর্শিত হওয়ার পরে ঘটতে পারেসময় হওয়ার আগে একবারের পরিবর্তে দুই ঘন্টার পরিবর্তে এক ঘন্টার সাথে সামঞ্জস্য হয়। একটি চূড়ান্ত উদাহরণ একটি পৃষ্ঠাগুলি যা 05:59 ইউটিসি-তে ঘটেছিল, তারপরে 06:00 ইউটিসিতে ঘটে এমন একটি ক্লিক। ইউটিসির সময়গুলিতে এক মিনিটের ব্যবধানে এগুলি ঘটেছিল, তবে পূর্ব সময়ের রূপান্তরিত হওয়ার সময়, দৃশ্যটি 1:59 পূর্বাহ্নে ঘটেছিল এবং ক্লিকটি এক ঘন্টা আগে ঘটেছিল।

  • 2014-03-09 02:30 মার্কিন যুক্তরাষ্ট্রে কখনই ঘটে না। এটি হ'ল সকাল 2:00 টায় আমরা ঘড়িগুলি সকাল 3:00 টায় রোল করি। ব্যবহারকারী সম্ভবত যদি এমন সময়ে প্রবেশ করে এবং আপনাকে এটিটি ইউটিসি তে রূপান্তর করতে বলেন বা আপনার ফর্মটি ডিজাইন করতে বলেছেন যাতে ব্যবহারকারীরা এমন সময় বাছতে না পারে তাই সম্ভবত আপনি কোনও ত্রুটি বাড়িয়ে তুলতে চাইবেন।

এমনকি এই প্রান্তের কেসগুলি মাথায় রেখে আমি এখনও মনে করি আপনার সঠিক পন্থা রয়েছে: ইউটিসিতে ডেটা সংরক্ষণ করুন। কিছু সময় অঞ্চল থেকে অন্য সময় অঞ্চল থেকে ইউটিসি থেকে অন্য সময় অঞ্চলগুলিতে ডেটা ম্যাপ করা অনেক সহজ, বিশেষত যখন বিভিন্ন সময় অঞ্চল বিভিন্ন তারিখে ডিএসটি শুরু / শেষ করে এবং এমনকি একই সময় অঞ্চল বিভিন্ন বছরে বিভিন্ন বিধি ব্যবহার করে স্যুইচ করতে পারে ( উদাহরণস্বরূপ, মার্কিন যুক্তরাষ্ট্র 6 বছর বা তার আগে নিয়মগুলি পরিবর্তন করেছে)।

আপনি এই সমস্তটির জন্য একটি ক্যালেন্ডার টেবিলটি ব্যবহার করতে চাইবেন, কিছুটা বড় CASE অভিব্যক্তি নয় ( বিবৃতি নয় )। আমি এমএসএসকিউএলটিপস.কম এর জন্য এই তিনটি অংশের সিরিজটি লিখেছি ; আমি মনে করি যে তৃতীয় অংশটি আপনার পক্ষে সবচেয়ে কার্যকর হবে:

http://www.mssqltips.com/sqlservertip/3173/handle-conversion-between-time-zones-in-sql-server--part-1/

http://www.mssqltips.com/sqlservertip/3174/handle-conversion-between-time-zones-in-sql-server--part-2/

http://www.mssqltips.com/sqlservertip/3175/handle-conversion-between-time-zones-in-sql-server--part-3/


এর মধ্যে একটি বাস্তব জীবন্ত উদাহরণ

ধরা যাক আপনার একটি খুব সাধারণ ফ্যাক্ট টেবিল রয়েছে। এক্ষেত্রে আমি কেবলমাত্র যত্ন নেওয়ার বিষয়টি ইভেন্টের সময়, তবে কেবলমাত্র যত্ন নেওয়ার পক্ষে টেবিলটিকে প্রশস্ত করতে কেবল অর্থহীন জিইউডি যুক্ত করব। আবার, স্পষ্টভাবে বলতে গেলে, তথ্য সারণী কেবলমাত্র ইউটিসি সময় এবং ইউটিসি সময়গুলিতে ইভেন্টগুলি সঞ্চয় করে। এমনকি কলামটিও আমি প্রত্যাহার করে নিয়েছি _UTCতাই কোনও বিভ্রান্তি নেই।

CREATE TABLE dbo.Fact
(
  EventTime_UTC DATETIME NOT NULL,
  Filler UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID()
);
GO

CREATE CLUSTERED INDEX x ON dbo.Fact(EventTime_UTC);
GO

এখন, আসুন 10,000,000 সারি দিয়ে আমাদের ফ্যাক্ট টেবিলটি লোড করুন - প্রতি রাতে 3 সেকেন্ড (প্রতি ঘন্টা 1,200 সারি) প্রতিনিধিত্ব করে 2013-12-30 থেকে মধ্যরাত ইউটিসি-এ 2014-12-12 এ 5 টা ইউটিসি-র পরে কিছুটা সময় অবধি। এটি নিশ্চিত করে যে ডেটা এক বছরের সীমানা বিভক্ত করে, পাশাপাশি ডিএসটি একসাথে এবং একাধিক সময় অঞ্চলের পিছনে থাকে। এটি সত্যিই ভীতিজনক মনে হচ্ছে, তবে আমার সিস্টেমে ~ 9 সেকেন্ড সময় নিয়েছে। টেবিলটি প্রায় 325 এমবি হওয়া উচিত।

;WITH x(c) AS 
(
  SELECT TOP (10000000) DATEADD(SECOND, 
    3*(ROW_NUMBER() OVER (ORDER BY s1.[object_id])-1),
    '20131230')
  FROM sys.all_columns AS s1
  CROSS JOIN sys.all_columns AS s2
  ORDER BY s1.[object_id]
)
INSERT dbo.Fact WITH (TABLOCKX) (EventTime_UTC) 
  SELECT c FROM x;

এবং কেবল এই সন্ধানের 10 মিমি সারি সারণির বিপরীতে একটি সাধারণ সন্ধানের ক্যোয়ারী কেমন হবে তা দেখানোর জন্য, যদি আমি এই কোয়েরিটি চালাই:

SELECT DATEADD(HOUR, DATEDIFF(HOUR, 0, EventTime_UTC), 0),
  COUNT(*)
FROM dbo.Fact 
WHERE EventTime_UTC >= '20140308'
AND EventTime_UTC < '20140311'
GROUP BY DATEADD(HOUR, DATEDIFF(HOUR, 0, EventTime_UTC), 0);

আমি এই পরিকল্পনাটি পেয়েছি এবং এটি 25 মিলিসেকেন্ডে * ফিরে আসে, 358 টি পাঠ করে, 72 ঘন্টা প্রতি ঘণ্টায় মোট ফিরে আসে:

এখানে চিত্র বর্ণনা লিখুন

* আমাদের নিখরচায় এসকিউএল সেন্ট্রি প্ল্যান এক্সপ্লোরার দ্বারা পরিমাপকৃত সময়কাল , যা ফলাফলগুলি বাতিল করে দেয়, সুতরাং এতে ডেটা, স্থানান্তর ইত্যাদির নেটওয়ার্ক ট্রান্সফার সময় অন্তর্ভুক্ত হয় না অতিরিক্ত অস্বীকৃতি হিসাবে, আমি এসকিউএল সেন্ট্রিয়ের জন্য কাজ করি।

এটি একটু বেশি সময় নেয়, স্পষ্টতই, আমি যদি আমার পরিসরটি আরও বড় করে তুলি - এক মাসের ডেটা 258ms সময় নেয়, দু'মাসে 500 মিমি বেশি সময় নেয় এবং আরও অনেক কিছু। সমান্তরালতা এড়ায়:

এখানে চিত্র বর্ণনা লিখুন

আপনি এখানে অন্যান্য প্রতিবেদন জিজ্ঞাসাগুলি পূরণের আরও ভাল সমাধান সম্পর্কে চিন্তাভাবনা শুরু করেছেন এবং আপনার আউটপুটটি কোন টাইম জোনে প্রদর্শিত হবে তার সাথে কিছুই করার নেই is আমি তাতে won'tুকব না, আমি কেবল এটিই প্রদর্শন করতে চাই যে টাইম জোনের রূপান্তরটি আপনার প্রতিবেদনের অনুসন্ধানগুলি আরও অনেক বেশি চুষিয়ে তুলবে না এবং আপনি ইতিমধ্যে চওড়াতে পারেন যদি আপনি যথাযথভাবে সমর্থন করেন না এমন বড় পরিসীমা পেয়ে যাচ্ছেন proper ইনডেক্স। যুক্তিটি সঠিক কিনা তা দেখানোর জন্য আমি ছোট তারিখের রেঞ্জগুলিতে আটকে যাচ্ছি এবং আপনার পরিসর-ভিত্তিক রিপোর্টিং কোয়েরিগুলি সময় অঞ্চল রূপান্তরগুলির সাথে বা ছাড়াই পর্যাপ্ত পরিমাণে সম্পাদন করে তা নিশ্চিত করার বিষয়ে আপনাকে চিন্তিত করতে দিন।

ঠিক আছে, এখন আমাদের আমাদের সময় অঞ্চলগুলি সংরক্ষণের জন্য টেবিলগুলির প্রয়োজন (অফসেট সহ, কয়েক মিনিটের মধ্যে, যেহেতু প্রত্যেকে ইউটিসি থেকে কয়েক ঘণ্টারও দূরে থাকে না) এবং প্রতিটি সমর্থিত বছরের জন্য ডিএসটি পরিবর্তনের তারিখ রয়েছে। সরলতার জন্য, আমি উপরের ডেটার সাথে মেলে কয়েকটি সময় অঞ্চল এবং একক বছর প্রবেশ করতে যাচ্ছি।

CREATE TABLE dbo.TimeZones
(
  TimeZoneID TINYINT    NOT NULL PRIMARY KEY,
  Name       VARCHAR(9) NOT NULL,
  Offset     SMALLINT   NOT NULL, -- minutes
  DSTName    VARCHAR(9) NOT NULL,
  DSTOffset  SMALLINT   NOT NULL  -- minutes
);

বৈচিত্র্যের জন্য কয়েকটি সময় অঞ্চল অন্তর্ভুক্ত করা হয়েছে, কয়েকটি অর্ধ ঘন্টা অফসেট সহ কিছু, যা ডিএসটি পালন করে না। নোট করুন যে দক্ষিণ গোলার্ধের অস্ট্রেলিয়া আমাদের শীতের সময় ডিএসটি পালন করে, তাই তাদের ঘড়িগুলি এপ্রিল মাসে ফিরে আসে এবং অক্টোবরে এগিয়ে যায়। (উপরের টেবিলটি নামগুলি উল্টে রেখেছে, তবে দক্ষিণ গোলার্ধের সময় অঞ্চলগুলির জন্য কীভাবে এটি কোনও কম বিভ্রান্তিকর করা যায় তা আমি নিশ্চিত নই।)

INSERT dbo.TimeZones VALUES
(1, 'UTC',     0, 'UTC',     0),
(2, 'GMT',     0, 'BST',    60), 
     -- London = UTC in winter, +1 in summer
(3, 'EST',  -300, 'EDT',  -240), 
     -- East coast US (-5 h in winter, -4 in summer)
(4, 'ACDT',  630, 'ACST',  570), 
     -- Adelaide (Australia) +10.5 h Oct - Apr, +9.5 Apr - Oct
(5, 'ACST',  570, 'ACST',  570); 
     -- Darwin (Australia) +9.5 h year round

এখন, টিজেড কখন পরিবর্তন হয় তা জানতে একটি ক্যালেন্ডার সারণী। আমি কেবল আগ্রহের সারিগুলি সন্নিবেশ করতে যাচ্ছি (উপরে প্রতিটি সময় অঞ্চল এবং 2014 এর জন্য কেবল ডিএসটি পরিবর্তন)। পিছনে পিছনে গণনার স্বাচ্ছন্দ্যের জন্য, আমি উভয় মুহূর্তটি ইউটিসি-তে সংরক্ষণ করি যেখানে একটি সময় অঞ্চল পরিবর্তন হয় এবং একই মুহূর্তটি স্থানীয় সময়। সময় অঞ্চলগুলি যা ডিএসটি পর্যবেক্ষণ করে না, এটি সারা বছর ধরে স্ট্যান্ডার্ড এবং 1 জানুয়ারি থেকে ডিএসটি "শুরু" হয়।

CREATE TABLE dbo.Calendar
(
  TimeZoneID    TINYINT NOT NULL FOREIGN KEY
                REFERENCES dbo.TimeZones(TimeZoneID),
  [Year]        SMALLDATETIME NOT NULL,
  UTCDSTStart   SMALLDATETIME NOT NULL,
  UTCDSTEnd     SMALLDATETIME NOT NULL,
  LocalDSTStart SMALLDATETIME NOT NULL,
  LocalDSTEnd   SMALLDATETIME NOT NULL,
  PRIMARY KEY (TimeZoneID, [Year])
);

আপনি এটিকে অবশ্যই অ্যালগরিদম দিয়ে পপুলেট করতে পারেন (এবং আসন্ন টিপ সিরিজটি কিছু চালাক সেট-বেসড কৌশল ব্যবহার করে, যদি আমি নিজেই তাই বলে থাকি), লুপের পরিবর্তে, ম্যানুয়ালি পপুলেট করুন, আপনার কী আছে। এই উত্তরের জন্য আমি পাঁচ বারের অঞ্চলগুলির জন্য কেবল এক বছর ম্যানুয়ালি آباد করার সিদ্ধান্ত নিয়েছি এবং আমি কোনও অভিনব কৌশলকে বিরক্ত করব না।

INSERT dbo.Calendar VALUES
(1, '20140101', '20140101 00:00','20150101 00:00','20140101 00:00','20150101 00:00'),
(2, '20140101', '20140330 01:00','20141026 00:00','20140330 02:00','20141026 01:00'),
(3, '20140101', '20140309 07:00','20141102 06:00','20140309 03:00','20141102 01:00'),
(4, '20140101', '20140405 16:30','20141004 16:30','20140406 03:00','20141005 02:00'),
(5, '20140101', '20140101 00:00','20150101 00:00','20140101 00:00','20150101 00:00');

ঠিক আছে, সুতরাং আমাদের কাছে আমাদের ফ্যাক্ট ডেটা এবং আমাদের "মাত্রা" সারণী রয়েছে (যখন আমি এটি বলি তখন কুঁকড়ে যাই), সুতরাং যুক্তিটি কী? ঠিক আছে, আমি অনুমান করি আপনি ব্যবহারকারীদের তাদের সময় অঞ্চলটি নির্বাচন করতে এবং ক্যোয়ারির জন্য তারিখের সীমাটি প্রবেশ করতে চলেছেন। আমি এও ধরে নেব যে তারিখের সীমাটি তাদের নিজস্ব সময় অঞ্চলে পুরো দিন হবে; কোন আংশিক দিন, আংশিক ঘন্টা মনে করবেন না। সুতরাং তারা একটি শুরুর তারিখ, শেষের তারিখ এবং একটি সময় জোনে পাস করবে। সেখান থেকে আমরা সেই সময় অঞ্চল থেকে শুরু করে ইউটিসিতে সূচনা / শেষের তারিখ রূপান্তর করতে একটি স্কেলার ফাংশন ব্যবহার করব, যা আমাদের ইউটিসি রেঞ্জের উপর ভিত্তি করে ডেটা ফিল্টার করতে দেয়। একবার এটি হয়ে গেলে এবং এতে আমাদের সমষ্টি সম্পাদন করা হলে, আমরা তারপরে ব্যবহারকারীর কাছে প্রদর্শিত হওয়ার আগে গ্রুপযুক্ত সময়ের রূপান্তরটি উত্স সময় অঞ্চলে ফিরে প্রয়োগ করতে পারি।

স্কেলার ইউডিএফ:

CREATE FUNCTION dbo.ConvertToUTC
(
  @Source   SMALLDATETIME,
  @SourceTZ TINYINT
)
RETURNS SMALLDATETIME
WITH SCHEMABINDING
AS
BEGIN
  RETURN 
  (
    SELECT DATEADD(MINUTE, -CASE 
        WHEN @Source >= src.LocalDSTStart 
         AND @Source < src.LocalDSTEnd THEN t.DSTOffset 
        WHEN @Source >= DATEADD(HOUR,-1,src.LocalDSTStart) 
         AND @Source < src.LocalDSTStart THEN NULL
        ELSE t.Offset END, @Source)
    FROM dbo.Calendar AS src
    INNER JOIN dbo.TimeZones AS t 
    ON src.TimeZoneID = t.TimeZoneID
    WHERE src.TimeZoneID = @SourceTZ 
      AND t.TimeZoneID = @SourceTZ
      AND DATEADD(MINUTE,t.Offset,@Source) >= src.[Year]
      AND DATEADD(MINUTE,t.Offset,@Source) < DATEADD(YEAR, 1, src.[Year])
  );
END
GO

এবং টেবিলের মূল্যবান ফাংশন:

CREATE FUNCTION dbo.ConvertFromUTC
(
  @Source   SMALLDATETIME,
  @SourceTZ TINYINT
)
RETURNS TABLE
WITH SCHEMABINDING
AS
 RETURN 
 (
  SELECT 
     [Target] = DATEADD(MINUTE, CASE 
       WHEN @Source >= trg.UTCDSTStart 
        AND @Source < trg.UTCDSTEnd THEN tz.DSTOffset 
       ELSE tz.Offset END, @Source)
  FROM dbo.Calendar AS trg
  INNER JOIN dbo.TimeZones AS tz
  ON trg.TimeZoneID = tz.TimeZoneID
  WHERE trg.TimeZoneID = @SourceTZ 
  AND tz.TimeZoneID = @SourceTZ
  AND @Source >= trg.[Year] 
  AND @Source < DATEADD(YEAR, 1, trg.[Year])
);

এবং একটি পদ্ধতি যা এটি ব্যবহার করে ( সম্পাদনা করুন : 30 মিনিটের অফসেট গ্রুপিং পরিচালনা করতে আপডেট হয়েছে):

CREATE PROCEDURE dbo.ReportOnDateRange
  @Start      SMALLDATETIME, -- whole dates only please! 
  @End        SMALLDATETIME, -- whole dates only please!
  @TimeZoneID TINYINT
AS 
BEGIN
  SET NOCOUNT ON;

  SELECT @Start = dbo.ConvertToUTC(@Start, @TimeZoneID),
         @End   = dbo.ConvertToUTC(@End,   @TimeZoneID);

  ;WITH x(t,c) AS
  (
    SELECT DATEDIFF(MINUTE, @Start, EventTime_UTC)/60, 
      COUNT(*) 
    FROM dbo.Fact 
    WHERE EventTime_UTC >= @Start
      AND EventTime_UTC <  DATEADD(DAY, 1, @End)
    GROUP BY DATEDIFF(MINUTE, @Start, EventTime_UTC)/60
  )
  SELECT 
    UTC = DATEADD(MINUTE, x.t*60, @Start), 
    [Local] = y.[Target], 
    [RowCount] = x.c 
  FROM x OUTER APPLY 
    dbo.ConvertFromUTC(DATEADD(MINUTE, x.t*60, @Start), @TimeZoneID) AS y
  ORDER BY UTC;
END
GO

(আপনি সেখানে সংক্ষিপ্ত সার্কিটে যেতে চান বা কোনও পৃথক স্টোরেজ পদ্ধতি ব্যবহার করতে পারেন, ব্যবহারকারী যদি ইউটিসিতে রিপোর্ট করতে চান - স্পষ্টতই ইউটিসি-তে অনুবাদ করা ব্যর্থ ব্যস্ততার কাজ হয়ে যাবে।)

নমুনা কল:

EXEC dbo.ReportOnDateRange 
  @Start      = '20140308', 
  @End        = '20140311', 
  @TimeZoneID = 3;

41ms * এ ফিরে আসে এবং এই পরিকল্পনাটি উত্পন্ন করে:

এখানে চিত্র বর্ণনা লিখুন

* আবার, বাতিল ফলাফল সহ।

2 মাসের জন্য, এটি 507ms এ ফিরে আসে এবং প্ল্যানটি সারি অ্যাকাউন্টগুলির তুলনায় অন্যরকম:

এখানে চিত্র বর্ণনা লিখুন

যদিও আরও জটিল এবং রান সময়কে কিছুটা বাড়িয়ে তুলছে, আমি যথেষ্ট আস্থাশীল যে এই ধরণের পদ্ধতির ব্রিজ টেবিল পদ্ধতির চেয়ে অনেক বেশি কার্যকর হবে। এবং এটি একটি ডিবিএ.এস উত্তরের জন্য অফ-কাফ উদাহরণ; আমি নিশ্চিত যে আমার যুক্তি এবং দক্ষতা আমার চেয়ে অনেক বেশি স্মার্ট লোকেরা উন্নত করতে পারে।

আমি যে প্রান্তের বিষয়ে কথা বলি সেগুলি দেখার জন্য আপনি ডেটা ব্যবহার করতে পারেন - ঘড়িগুলি যেদিকে এগিয়ে চলেছে এমন এক ঘণ্টার জন্য কোনও আউটপুটের সারি নেই, যেখানে তারা ঘুরেছে তার জন্য দুটি সারি (এবং সেই ঘন্টাটি দু'বার হয়েছিল)। আপনি খারাপ মান দিয়েও খেলতে পারেন; আপনি যদি 20140309 02:30 পূর্বের সময়টি পাস করেন তবে উদাহরণস্বরূপ, এটি খুব ভালভাবে কাজ করবে না।

আপনার প্রতিবেদনটি কীভাবে কাজ করবে সে সম্পর্কে আমার কাছে সমস্ত অনুমানগুলি নাও থাকতে পারে, তাই আপনাকে কিছুটা সামঞ্জস্য করতে হতে পারে। তবে আমি মনে করি এটিতে বেসিকগুলি অন্তর্ভুক্ত।


0

আপনি কি উপস্থাপনা স্তরের পরিবর্তে কোনও সঞ্চয় স্থান বা প্যারামিটারাইজড ভিউতে রূপান্তর করতে পারেন? আর একটি বিকল্প কিউব তৈরি করা এবং কিউবে গণনা করা।

মন্তব্য থেকে ব্যাখ্যা:

উপস্থাপনা স্তরে গণনা করে ওপি তার সীমিত পরীক্ষার সাথে পারফরম্যান্স ইস্যুগুলিতে ছড়িয়ে পড়ে। আমার পরামর্শ হ'ল এটি ডাটাবেসে সরিয়ে নেওয়া। স্কয়ারে, আপনি একটি টেবিলের মূল্যবান ফাংশন ব্যবহার করে একটি প্যারামিটারাইজড ভিউ করতে পারেন। এই ফাংশনে পাস করা সময় অঞ্চলটির ভিত্তিতে, ইউটিসি টেবিল থেকে ডেটা গণনা করা যায় এবং ফিরে আসতে পারে। আশা করি এটি আমার মূল উত্তরটি পরিষ্কার করে দিয়েছে।


সুতরাং এমন একটি দর্শন যেখানে 100+ অতিরিক্ত কলাম রয়েছে যেখানে প্রতিটি সারিতে ইউটিসিতে উত্স সময়কে সমস্ত 100+ টাইম জোনে অনুবাদ করে? এমনকি এমন দৃশ্য কীভাবে লেখা হবে তা আমিও জানতে শুরু করতে পারি না। এছাড়াও লক্ষ করুন এসকিউএল সার্ভারের কোনও "প্যারামিটারাইজড ভিউ" নেই ...
অ্যারন বারট্রান্ড

হুম .. তাই আপনি কি ভাবছেন। এবং এটাই আমি বোঝাতে চাইনি
কেএনআই

1
সুতরাং আমাকে অন্যথায় চিন্তা করতে। আমি কোনওভাবেই ডাউন-ভোট ছিলাম না, কেবলমাত্র আপনার উত্তরে আরও স্পষ্টতাকে উত্সাহিত করার চেষ্টা করছি।
অ্যারন বার্ট্র্যান্ড

অপশন উপস্থাপনা স্তরে গণনা করে তার সীমাবদ্ধ পরীক্ষা নিয়ে পারফরম্যান্স ইস্যুগুলিতে ছড়িয়ে পড়ে। আমার পরামর্শ হ'ল এটি ডাটাবেসে সরিয়ে নেওয়া। স্কয়ারে, আপনি একটি টেবিলের মূল্যবান ফাংশন ব্যবহার করে একটি প্যারামিটারাইজড ভিউ করতে পারেন। এই ফাংশনে পাস করা সময় অঞ্চলের ভিত্তিতে ডেটা গণনা করা যায় এবং ইউটিসি টেবিল থেকে ফিরে আসতে পারে। আশা করি এটি আমার মূল উত্তরটি পরিষ্কার করে দিয়েছে।
কেএনআই

ডেটা একত্রিত হলে কীভাবে এটি কাজ করতে পারে? যদি টাইমজোনটি 30 মিনিট অফসেট থাকে তবে ডেটা অন্য গোষ্ঠীতে পড়বে। আপনি কেবল উপস্থাপনা স্তরে প্রদর্শিত লেবেলগুলি পরিবর্তন করতে পারবেন না।
কলিন টি হার্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.