এক টেবিলের অস্তিত্বহীন সারিগুলির সাথে সারিগুলি দেখানোর জন্য এসকিউএল কোয়েরিতে যোগদান করুন


12

আমি কর্মীদের সময় রেকর্ড জন্য কিছু রিপোর্টিং সম্পন্ন করার চেষ্টা করছি।

এই প্রশ্নের জন্য আমাদের দুটি সারণী বিশেষত রয়েছে। কর্মচারীদের Membersটেবিলের তালিকাভুক্ত করা হয় এবং প্রতিটি দিন তারা যে কাজ সম্পাদন করে তার Time_Entryটেবিলে সঞ্চিত থাকে এবং তার জন্য প্রবেশের সময় প্রবেশ করে ।

এসকিউএল ফিডল সহ সেটআপ উদাহরণ: http://sqlfiddle.com/#!3/e3806/7

শেষ ফলাফল আমি যাচ্ছি একটি টেবিল যা শো হয় সবMembers একটি কলাম তালিকায় এবং তারপর অন্যান্য কলামে জানতে চাওয়া তারিখ জন্য তাদের যোগফল ঘণ্টা প্রদর্শন করবে।

সমস্যাটি মনে হচ্ছে যদি কোনও Time_Entryনির্দিষ্ট সদস্যের জন্য টেবিলে কোনও সারি না থাকে তবে সেই সদস্যের জন্য এখন সারি রয়েছে। আমি বেশ কয়েকটি পৃথক জোনের প্রকার চেষ্টা করেছি (বাম, ডান, অভ্যন্তরীণ, আউটার, পূর্ণ আউটার, ইত্যাদি) তবে কেউই আমার যা চাইবে তা দেয় না বলে মনে হয় (এসকিউএল ফিডেলের শেষ উদাহরণের ভিত্তিতে):

/*** Desired End Result ***/

Member_ID   | COUNTTime_Entry | TIMEENTRYDATE | SUMHOURS_ACTUAL | SUMHOURS_BILL
ADavis      | 0               | 11-10-2013    | 0               | 0
BTronton    | 0               | 11-10-2013    | 0               | 0
CJones      | 0               | 11-10-2013    | 0               | 0
DSmith      | 0               | 11-10-2013    | 0               | 0
EGirsch     | 1               | 11-10-2013    | 0.92            | 1
FRowden     | 0               | 11-10-2013    | 0               | 0

11-1-র নির্দিষ্ট তারিখের জন্য আমি যখন জিজ্ঞাসা করি তখন আমি এখন কী পাচ্ছি:

Member_ID   | COUNTTime_Entry | TIMEENTRYDATE | SUMHOURS_ACTUAL | SUMHOURS_BILL
EGirsch     | 1               | 11-10-2013    | 0.92            | 1

যা ইজির্শের জন্য ১১-১০-২০১৩ তারিখের এককালীন এন্ট্রি সারির ভিত্তিতে সঠিক, তবে এই তথ্যের জন্য আমাকে অন্যান্য সদস্যদের জন্য জিরোগুলি দেখতে হবে এবং শেষ পর্যন্ত একটি ওয়েব ড্যাশবোর্ড / প্রতিবেদন পেতে হবে।

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

উত্তর:


11

এসকিউএলফিডাল এবং নমুনা ডেটার জন্য আপনাকে ধন্যবাদ! আমি আশা করি আরও প্রশ্ন এইভাবে শুরু করা উচিত।

আপনি যদি members তারিখের জন্য কোনও প্রবেশিকা আছে কিনা তা নির্বিশেষে যদি আপনি সমস্ত সদস্য চান তবে আপনি একটি চান LEFT OUTER JOIN। আপনি এই সংস্করণটির সাথে খুব কাছাকাছি ছিলেন তবে বাইরের সাথে যোগ দেওয়ার সাথে সামান্য কৌশলটি হ'ল আপনি যদি ধারাটিতে বাইরের টেবিলে একটি ফিল্টার যুক্ত করেন তবে আপনি WHEREএকটি বাহ্যিক জোড়কে অভ্যন্তরীণ জোড়ায় পরিণত করেন, কারণ এটি কোনও NULLপাশের সারি বাদ দেবে it (কারণ এটি জানে না NULLযে ফিল্টারটি মেলে কিনা )

আমি প্রতিটি সদস্যের জন্য একটি সারি পেতে প্রথম ক্যোয়ারীটি সংশোধন করেছি:

SELECT Members.Member_ID
      ,Time_Entry.Date_Start
      ,Time_Entry.Hours_Actual
      ,Time_Entry.Hours_Bill
FROM dbo.Members
  LEFT OUTER JOIN dbo.Time_Entry
--^^^^ changed from FULL to LEFT
  ON Members.Member_ID = Time_Entry.Member_ID
  AND Time_Entry.Date_Start = '20131110';
--^^^ changed from WHERE to AND

আমি এটিকে সেখান থেকে নেওয়ার জন্য এবং অন্যান্য কলাম, বিন্যাস COALESCEইত্যাদি যুক্ত করার জন্য এটি অনুশীলন হিসাবে রেখে দেব

কিছু অন্যান্য নোট:


হারুন, প্রতিক্রিয়ার জন্য অনেক ধন্যবাদ। এসকিউএল নবাগত এখানে, এবং কোন ধারণা মধ্যে পার্থক্য ছিল WHEREএবং AND। আমি প্রাথমিকভাবে এলিয়াস ব্যবহার করেছি, তবে স্ক্লফিল্ড এটি পছন্দ করবে বলে মনে হচ্ছে না তাই আমি পুরো ফর্ম্যাটটিতে চলেছি। অন্যান্য এসকিউএল টিপসের জন্যও ধন্যবাদ। আপনি কি সুপারিশ করবেন ISNULLবা পরিবর্তে 0COALESCE ডেটা তৈরি করবেন ? আবার ধন্যবাদ! NULL
বিদায়দিন

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

4

অতীতে যখন আমি এই ধরণের সমস্যার মুখোমুখি হয়েছি তখন হারিয়ে যাওয়া সারিগুলি মোকাবেলা করতে আমি একটি "সংখ্যা" সারণী তৈরি করেছি ।

তারিখগুলি মোকাবেলা করার জন্য আমি আমার নম্বর সারণীটি বিশেষভাবে তৈরি করেছি:

CREATE TABLE Dates
(
    dDate DATETIME NOT NULL CONSTRAINT PK_Dates PRIMARY KEY CLUSTERED
);

INSERT INTO Dates (dDate)
SELECT TOP(73049) DATEADD(d, -1, ROW_NUMBER() OVER (ORDER BY o.object_id)) AS dDate
FROM master.sys.objects o, master.sys.objects o1, master.sys.objects o2

এটি 1900-01-01 এবং 2099-12-31 এর মধ্যে প্রতিটি তারিখের জন্য একক সারি সহ একটি টেবিল তৈরি করে। আমি TOP(73049)আমার উদাহরণে উত্পন্ন তারিখের সীমাটি আপনার তারিখগুলিতে সীমাবদ্ধ করতে ব্যবহার করি - আপনি যদি কোনও ভিন্ন তারিখের সীমা নিয়ে কাজ করেন তবে আপনি সেই নম্বরটি সামঞ্জস্য করতে পারেন।

এরপরে, আমি dDatesআমার ক্যোয়ারীতে টেবিলটি যুক্ত করব যাতে প্রতিটির জন্য কাঙ্ক্ষিত ব্যাপ্তিতে প্রতিটি তারিখের জন্য একটি সারি ফিরে আসে member_id। ফলস্বরূপ Time_Entryটেবিলে এইভাবে যুক্ত হবে :

SELECT MD.Member_ID,
    MD.dDate,
    T.Date_Start,
    T.Hours_Actual,
    T.Hours_Bill
FROM 
    (
        SELECT M.Member_ID, D.dDate
        FROM dbo.Dates D, dbo.Members M
        WHERE D.dDate >= '20131110' AND D.dDate < '20131112'
    ) AS MD
    LEFT JOIN dbo.Time_Entry T ON MD.Member_ID = T.Member_ID AND MD.dDate = T.Date_Start
ORDER BY MD.Member_ID, MD.dDate

এটি আপনাকে প্রতিবেদনের জন্য একটি তারিখের সীমা নির্দিষ্ট করতে দেয়।

আপনি যোগ করে COALESCE(...)এবং SUM(...)অনুযায়ী ফলাফলগুলি আরও পরিমার্জন করতে পারেন :

SELECT MD.Member_ID,
    MD.dDate,
    T.Date_Start,
    SUM(COALESCE(T.Hours_Actual, 0)) AS TotalHoursActual,
    SUM(COALESCE(T.Hours_Bill, 0)) AS TotalHoursBill
FROM 
    (
        SELECT M.Member_ID, D.dDate
        FROM dbo.Dates D, dbo.Members M
        WHERE D.dDate >= '20131110' AND D.dDate < '20131112'
    ) AS MD
    LEFT JOIN dbo.Time_Entry T ON MD.Member_ID = T.Member_ID AND MD.dDate = T.Date_Start
GROUP BY MD.Member_ID, MD.dDate, T.Date_Start
ORDER BY MD.Member_ID, MD.dDate

এটি আপনার নমুনা ডেটার জন্য নিম্নলিখিত আউটপুট ফলাফল:

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


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

1
@ সানক্যাট 2000 - সম্মত হয়েছে, যদিও আমি "সংখ্যার সারণী" নামটি পছন্দ করি যেহেতু সংখ্যার সাথে সংখ্যায় বোঝানো হয় এবং আমার অভিজ্ঞতায় এই প্যাটার্নটি গাণিতিক ক্রিয়াকলাপের জন্য খুব কমই ব্যবহৃত হয়। তারা অনেক কিছুর জন্য দুর্দান্ত, তবে অবশ্যই আপনি পেতে পারেন সবচেয়ে বড় পারফরম্যান্স উন্নতিগুলির মধ্যে একটি হল একটি নম্বর সারণী ব্যবহার করে একটি আরবিআর পদ্ধতির কাছ থেকে, সেট-ভিত্তিক পদ্ধতির দিকে যাওয়া।
ম্যাক্স ভার্নন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.