দুটি সম্পর্কিত "অনেকগুলি" সারণী সহ কোনও টেবিলের ফলাফল কীভাবে সমতল করা যায়?


9

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

আমার কাছে নিম্নলিখিত সারণী রয়েছে (কিছুটা পরিষ্কার উদাহরণের জন্য সংক্ষেপিত):

CREATE TABLE Loans(
    Id int,
    SchemaId int,
    LoanNumber nvarchar(100)
);

CREATE TABLE SchemaFields(
    Id int,
    SchemaId int,
    FieldName nvarchar(255)
);

CREATE TABLE LoanFields(
    Id int,
    LoanId int,
    SchemaFieldId int,
    FieldValue nvarchar(4000)
);

নিম্নলিখিত তথ্য সহ:

INSERT INTO Loans (Id, SchemaId, LoanNumber) VALUES (1, 1, 'ABC123');

INSERT INTO SchemaFields (Id, SchemaId, FieldName) VALUES (1, 1, 'First Name');
INSERT INTO SchemaFields (Id, SchemaId, FieldName) VALUES (2, 1, 'Last Name');

INSERT INTO LoanFields (Id, LoanId, SchemaFieldId, FieldValue) VALUES (1, 1, 1, 'John');
INSERT INTO LoanFields (Id, LoanId, SchemaFieldId, FieldValue) VALUES (2, 1, 2, 'Doe');

উদ্দেশ্যটি এমন একটি কোয়েরি পাওয়া যা এর সমস্ত ক্ষেত্রের সাথে loanণের জন্য সমতল। (বাস্তব বিশ্বে সম্ভবত একই স্কীমার জন্য 20-30 ক্ষেত্রের মধ্যে থাকতে পারে, তবে আমাদের উদাহরণে কেবল 2 টি আছে):

LoanNumber   First Name    Last Name
----------   -----------   ----------
ABC123       John          Doe

আমি 'পাইভট' ব্যবহার করতে পারি না যা 'প্রথম নাম' এবং 'শেষ নাম' উল্লেখ করে কারণ সেখানে আসলে কী হবে সে সম্পর্কে আমার কোনও ধারণা নেই।

ইতিমধ্যে আমার কাছে স্কেমা সহ এখানে একটি এসকিউএল ফিডল রয়েছে

আমি কীভাবে পছন্দসই ফলাফল পেতে পারি?

উত্তর:


7

এটি PIVOT ফাংশনটি ব্যবহার করে করা যেতে পারে , তবে যেহেতু মনে হচ্ছে আপনি স্কিমাআইডের উপর ভিত্তি করে কোয়েরিটি পরিবর্তন করতে চান, আপনি ডায়নামিক এসকিউএল ব্যবহার করতে চাইবেন।

যদি আপনার নির্দিষ্ট সংখ্যক মান থাকে বা নির্দিষ্ট স্কিমাইডের জন্য কলামগুলি জানতেন তবে আপনি কোয়েরিটিকে কঠোরভাবে কোডিং করতে পারবেন। একটি স্থিত ক্যোয়ারী হবে:

select loannumber,
  [First Name], 
  [Middle Name], 
  [Last Name]
from
(
  select 
    l.loannumber,
    sf.fieldname,
    lf.fieldvalue
  from loans l
  left join loanfields lf
    on l.id = lf.loanid
  left join schemafields sf
    on lf.schemafieldid = sf.id
    and l.schemaid = sf.schemaid
) src
pivot
(
  max(fieldvalue)
  for fieldname in ([First Name], [Middle Name], [Last Name])
)piv;

ডেমো সহ এসকিউএল ফিডল দেখুন ।

যদি আপনার অজানা নম্বর থাকে বা আপনি SchemaIdযে পদ্ধতিতে যাচ্ছেন তার উপর ভিত্তি করে কলামগুলি পরিবর্তন করতে চান তবে আপনি এসকিউএল স্ট্রিং তৈরি করতে ডায়নামিক এসকিউএল ব্যবহার করবেন:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @schemaId int = 1

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(FieldName) 
                    from SchemaFields 
                    where schemaid = @schemaid
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT loannumber,' + @cols + ' 
            from 
            (
              select 
                l.loannumber,
                sf.fieldname,
                lf.fieldvalue
              from loans l
              left join loanfields lf
                on l.id = lf.loanid
              left join schemafields sf
                on lf.schemafieldid = sf.id
                and l.schemaid = sf.schemaid
              where sf.schemaid = '+cast(@schemaid as varchar(10))+'
            ) x
            pivot 
            (
                max(fieldvalue)
                for fieldname in (' + @cols + ')
            ) p '

execute(@query);

ডেমো সহ এসকিউএল ফিডল দেখুন । এই উভয় প্রশ্নেরই ফলাফল উত্পন্ন হবে:

| LOANNUMBER | FIRST NAME | LAST NAME | MIDDLE NAME |
-----------------------------------------------------
|     ABC123 |       John |       Doe |      (null) |
|     XYZ789 |    Charles |     Smith |         Lee |

3

আপনি এই প্যাটার্নটি ব্যবহার করতে পারেন। আরও স্কিমা ক্ষেত্রের জন্য, সমস্ত স্কিমা ক্ষেত্রের নামের সাথে কেবল দ্বিতীয় থেকে শেষ লাইনে প্রসারিত করুন।

select *
  from (
    select l.LoanNumber, s.FieldName, f.FieldValue
      from Loans l
      join Schemafields s on s.SchemaId = l.SchemaId
      join LoanFields f on f.LoanId = l.Id and f.SchemaFieldId = s.Id) p
pivot (
    max(FieldValue) for FieldName in ([First Name], [Last Name])
    ) v;

যদি প্রকারের SchemaId = 1ক্ষেত্রগুলির প্রতিনিধিত্ব করে Loanতবে আপনি schema field namesনীচের মতো কিছু ব্যবহারের সম্পূর্ণ তালিকাটিও গতিশীলভাবে তৈরি করতে পারেন।

declare @sql nvarchar(max) =
    stuff((select ',' + quotename(FieldName)
      from SchemaFields
     where SchemaId = 1
       for xml path(''), type).value('/','nvarchar(max)'),1,1,'');
select @sql = '
select *
  from (
    select l.LoanNumber, s.FieldName, f.FieldValue
      from Loans l
      join Schemafields s on s.SchemaId = l.SchemaId
      join LoanFields f on f.LoanId = l.Id and f.SchemaFieldId = s.Id) p
pivot (
    max(FieldValue) for FieldName in (' + @sql + ')
    ) v';
exec (@sql);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.