কমন সারণী এক্সপ্রেশন (সিটিই) কখন ব্যবহার করবেন


230

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

উত্তর:


197

একটি উদাহরণ, যদি আপনাকে একই তথ্য সেট করতে একাধিকবার উল্লেখ করতে / যোগ দিতে হয় তবে আপনি কোনও সিটিই নির্ধারণ করে এটি করতে পারেন। অতএব, এটি কোড পুনরায় ব্যবহারের একটি ফর্ম হতে পারে।

স্ব-রেফারেন্সিংয়ের উদাহরণ হ'ল পুনরাবৃত্তি: সিটিই ব্যবহার করে পুনরাবৃত্তির অনুসন্ধানগুলি

অনলাইনে বই থেকে নেওয়া মাইক্রোসফ্ট সংজ্ঞা জন্য :

একটি সিটিই ব্যবহার করা যেতে পারে:

  • একটি পুনরাবৃত্তি কোয়েরি তৈরি করুন। আরও তথ্যের জন্য, সাধারণ সারণী এক্সপ্রেশন ব্যবহার করে পুনরাবৃত্ত অনুসন্ধানগুলি দেখুন

  • যখন কোনও দৃশ্যের সাধারণ ব্যবহারের প্রয়োজন হয় না তখন কোনও দৃশ্যের বিকল্প হয়; এটি হল, আপনাকে মেটাডেটাতে সংজ্ঞাটি সংরক্ষণ করতে হবে না।

  • কোনও স্কেলার সাবলেট থেকে প্রাপ্ত কলাম বা গোপনীয় নয় বা বাহ্যিক অ্যাক্সেস সহ এমন কোনও ফাংশন দ্বারা গোষ্ঠীকরণ সক্ষম করুন।

  • একই বিবৃতিতে একাধিকবার ফলাফল টেবিলটি উল্লেখ করুন।


7
হাঁ। আপনি উদ্ভূত টেবিলটিতে স্বযুক্ত হতে পারবেন না। সিটিইতে স্ব-যোগদানের বিষয়টি এখনও বিবেচনা করার মতো নয় তবে এটির 2 টি পৃথক আহবান আপনাকে ছেড়ে দেবে।
মার্টিন স্মিথ

@ মার্টিন - আমি অবাক আপনি কি এই বিবৃতি ব্যাক আপ করতে পারেন?
রিচার্ডকিউই

@ জন ধন্যবাদ, আমি 4guysfromrolla.com/webtech/071906-1.shtml খুব দরকারী খুঁজে পেয়েছি
ইমাম

4
@ সাইবারকিউই - কোন বিট? যে একটি স্ব যোগদান যোগদান 2 টি ভিন্ন অনুরোধে নেতৃত্ব দেবে? এই উত্তরের উদাহরণটি দেখুন stackoverflow.com/questions/3362043/…
মার্টিন স্মিথ

4
সিটিই সম্পর্কে আকর্ষণীয় ঘটনা। আমি সর্বদা ভাবতাম যখন সিটিইতে একাধিকবার রেফারেন্স করা হয় তখন কেন সিটিইতে নতুনআইডি () পরিবর্তিত হয়। select top 100 * into #tmp from master..spt_values order by 1,2,3,4 select A.number, COUNT(*) from #tmp A inner join #tmp B ON A.number = B.number+1 group by A.numberবনামwith CTE AS (select top 100 * from master..spt_values order by 1,2,3,4) select A.number, COUNT(*) from CTE A inner join CTE B ON A.number = B.number+1 group by A.number
রিচার্ডকিউই

50

আমি এগুলি জটিল প্রশ্নগুলি বিশেষত জটিল যোগদান এবং উপ-কোয়েরিগুলি ভাঙ্গতে ব্যবহার করি। আমি খুঁজে পেয়েছি যে আমি এগুলি আরও বেশি করে 'সিউডো-ভিউ' হিসাবে ব্যবহার করছি যাতে আমার প্রশ্নের সন্ধানের অভিপ্রায়টি পেতে পারে।

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

সমস্যা হ'ল, 'সাধারণ উদাহরণগুলি' সম্ভবত সত্যই সিটিইর প্রয়োজন হয় না!

এখনও, খুব সহজ।


ঠিক আছে. আপনি কি এমন কিছু তুলনামূলক জটিল উদাহরণ দিয়ে মামলা করতে পারেন যা এই ধারণাটি সম্পর্কে আমার মাথাকে সহায়তা করতে পারে?
ইম্যাক ইমরান

28
"তাদের সম্পর্কে আমার একমাত্র অভিযোগ হ'ল এগুলি পুনরায় ব্যবহার করা যাবে না" - আপনি যে পুনরায় ব্যবহার করতে চান এমন একটি সিটিই একটি VIEW:) এর প্রার্থী হিসাবে বিবেচনা করা উচিত
ওনেডে যাহা

6
@ ওনাডেউইভেন: বোঝা গেছে, তবে এটি একটি বিশ্বব্যাপী দিকটি বোঝায় যে আমি সর্বদা স্বাচ্ছন্দ্য বোধ করি না। কখনও কখনও কোনও প্রোকের সুযোগের মধ্যে আমি কোনও সিটিই সংজ্ঞায়িত করতে এবং এটি নির্বাচন এবং আপডেটের জন্য ব্যবহার করতে পারি, বা বিভিন্ন টেবিল থেকে অনুরূপ ডেটা নির্বাচন করি।
n8wrl

5
যখন আমার একই সিটিইর একাধিকবার প্রয়োজন হয় তখন আমি এটিকে একটি অস্থায়ী টেবিলের মধ্যে খাওয়াই এবং তারপরে অস্থায়ী টেবিলটি আমার ইচ্ছামত ব্যবহার করি।
Fandango68

43

আমি সিটি এর ব্যবহার দেখতে দুটি কারণ রয়েছে।

যেখানে অনুচ্ছেদে একটি গণনা করা মান ব্যবহার করতে। এটি একটি উত্সযুক্ত টেবিলের তুলনায় আমার কাছে একটু ক্লিনার মনে হচ্ছে।

ধরুন এখানে দুটি সারণী রয়েছে - প্রশ্ন এবং উত্তরগুলি একসাথে প্রশ্ন.আইডি = উত্তরগুলি দিয়েছিলেন Q প্রশ্ন_আইডি (এবং কুইজ আইডি)

WITH CTE AS
(
    Select Question_Text,
           (SELECT Count(*) FROM Answers A WHERE A.Question_ID = Q.ID) AS Number_Of_Answers
    FROM Questions Q
)
SELECT * FROM CTE
WHERE Number_Of_Answers > 0

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

WITH cte AS
(
    SELECT [Quiz_ID] 
      ,[ID] AS Question_Id
      ,null AS Answer_Id
          ,[Question_Text]
          ,null AS Answer
          ,1 AS Is_Question
    FROM [Questions]

    UNION ALL

    SELECT Q.[Quiz_ID]
      ,[Question_ID]
      ,A.[ID] AS  Answer_Id
      ,Q.Question_Text
          ,[Answer]
          ,0 AS Is_Question
        FROM [Answers] A INNER JOIN [Questions] Q ON Q.Quiz_ID = A.Quiz_ID AND Q.Id = A.Question_Id
)
SELECT 
    Quiz_Id,
    Question_Id,
    Is_Question,
    (CASE WHEN Answer IS NULL THEN Question_Text ELSE Answer END) as Name
FROM cte    
GROUP BY Quiz_Id, Question_Id, Answer_id, Question_Text, Answer, Is_Question 
order by Quiz_Id, Question_Id, Is_Question Desc, Name

10
আপনার প্রথম উদাহরণটি কি কেবল সিটিইর পরিবর্তে নেস্টেড কোয়েরি ব্যবহার করতে সরল করা যায় না?
স্যাম

2
উভয় উদাহরণ হতে পারে।
মানাচি

3
আপনার প্রথমটি সিটিই ছাড়াই যুক্ত করা উচিত ছিল, তবে এটি পরবর্তীকালে কার্যকর কেন তা তাত্ক্ষণিকভাবে স্পষ্ট।
ইউফস

HAVINGদেরী-পর্যায়ের ফিল্টারটি করার অন্য উপায় যা একটি সাবSELECT
উইলিয়াম এন্টারিকেন

21

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

তবে সিটিই ব্যবহার করে ( রেকর্ডের প্রথম উদাহরণটি নির্বাচন করে টিম শেমলেটারের উত্তর অনুসারে )

WITH CTE AS(
    SELECT myTable.*
    , RN = ROW_NUMBER()OVER(PARTITION BY patientID ORDER BY ID)
    FROM myTable 
)
SELECT * FROM CTE
WHERE RN = 1

আপনি দেখতে পাচ্ছেন, এটি পড়া এবং বজায় রাখা আরও সহজ। এবং অন্যান্য প্রশ্নের তুলনায়, পারফরম্যান্সে অনেক ভাল।


16

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

  • একটি পুনরাবৃত্তি কোয়েরি তৈরি করুন।
  • আপনার কোয়েরিতে সিটিইর রেজাল্টটি একাধিকবার ব্যবহার করুন।
  • অভিন্ন অণুভাগের বৃহত অংশগুলি হ্রাস করে আপনার ক্যোয়ারীতে স্পষ্টতা প্রচার করুন।
  • সিটিইর ফলাফলসেটটিতে প্রাপ্ত কলাম দ্বারা গোষ্ঠীকরণ সক্ষম করুন

এখানে খেলতে কাট-পেস্টের উদাহরণ:

WITH [cte_example] AS (
SELECT 1 AS [myNum], 'a num' as [label]
UNION ALL
SELECT [myNum]+1,[label]
FROM [cte_example]
WHERE [myNum] <=  10
)
SELECT * FROM [cte_example]
UNION
SELECT SUM([myNum]), 'sum_all' FROM [cte_example]
UNION
SELECT SUM([myNum]), 'sum_odd' FROM [cte_example] WHERE [myNum] % 2 = 1
UNION
SELECT SUM([myNum]), 'sum_even' FROM [cte_example] WHERE [myNum] % 2 = 0;

উপভোগ করুন


7

আজ আমরা কমন টেবিল এক্সপ্রেশন সম্পর্কে শিখতে যা এটি একটি নতুন বৈশিষ্ট্য যা এসকিউএল সার্ভার 2005 সালে চালু হয়েছিল এবং পরবর্তী সংস্করণগুলিতেও উপলব্ধ।

সাধারণ সারণী এক্সপ্রেশন: - সাধারণ টেবিল এক্সপ্রেশনটি একটি অস্থায়ী ফলাফল সেট হিসাবে বা অন্য কথায় এটি এসকিউএল সার্ভারে দর্শনের বিকল্প হিসাবে সংজ্ঞায়িত করা যেতে পারে। সাধারণ সারণী প্রকাশটি কেবলমাত্র বিবৃতি ব্যাচে বৈধ যেখানে এটি সংজ্ঞায়িত হয়েছিল এবং অন্যান্য সেশনে ব্যবহার করা যাবে না।

সিটিই ঘোষণার সিনট্যাক্স (সাধারণ সারণী প্রকাশ): -

with [Name of CTE]
as
(
Body of common table expression
)

একটি উদাহরণ নেওয়া যাক:

CREATE TABLE Employee([EID] [int] IDENTITY(10,5) NOT NULL,[Name] [varchar](50) NULL)

insert into Employee(Name) values('Neeraj')
insert into Employee(Name) values('dheeraj')
insert into Employee(Name) values('shayam')
insert into Employee(Name) values('vikas')
insert into Employee(Name) values('raj')

CREATE TABLE DEPT(EID INT,DEPTNAME VARCHAR(100))
insert into dept values(10,'IT')
insert into dept values(15,'Finance')
insert into dept values(20,'Admin')
insert into dept values(25,'HR')
insert into dept values(10,'Payroll')

আমি দুটি টেবিল কর্মচারী এবং ডিপার্টমেন্ট তৈরি করেছি এবং প্রতিটি টেবিলে 5 টি সারি .োকিয়েছি। এখন আমি এই টেবিলগুলিতে যোগদান করতে এবং এটি আরও ব্যবহারের জন্য একটি অস্থায়ী ফলাফল সেট তৈরি করতে চাই।

With CTE_Example(EID,Name,DeptName)
as
(
select Employee.EID,Name,DeptName from Employee 
inner join DEPT on Employee.EID =DEPT.EID
)
select * from CTE_Example

স্টেটমেন্টের প্রতিটি লাইন একের পর এক নিতে দিন এবং বুঝতে দিন।

সিটিই সংজ্ঞায়িত করতে আমরা "সহ" ধারাটি লিখি, তারপরে আমরা টেবিলের অভিব্যক্তিটিকে একটি নাম দিই, এখানে আমি "CTE_Example" নাম দিয়েছি

তারপরে আমরা "As" লিখি এবং দুটি কোড বন্ধনী (---) এ আমাদের কোডটি বন্ধ করি, আমরা বদ্ধ বন্ধনীগুলিতে একাধিক টেবিলগুলিতে যোগদান করতে পারি।

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

With CTE_Example(EID,DeptName)
as
(
select EID,DeptName from DEPT 
)
delete from CTE_Example where EID=10 and DeptName ='Payroll'

উপরের বিবৃতিতে আমরা CTE_Example থেকে একটি সারি মুছে ফেলছি এবং এটি সিটিইতে ব্যবহৃত রেফারেন্স টেবিল "ডিইপিটি" থেকে ডেটা মুছে ফেলবে।


আমি এখনও পয়েন্ট পাই না। এর মধ্যে পার্থক্য কী এবং ঠিক একই শর্তের সাথে ডিইপিটি থেকে মুছতে পারে? এটি কিছু সহজ করে তোলে বলে মনে হয় না।
Holger Jakobs

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

7

আপনি যখন "অর্ডার করা আপডেট" করতে চান এটি খুব কার্যকর।

এমএস এসকিউএল আপনাকে আপডেটের মাধ্যমে অর্ডার ব্যবহারের অনুমতি দেয় না, তবে সিটিইর সহায়তায় আপনি সেভাবে এটি করতে পারেন:

WITH cte AS
(
    SELECT TOP(5000) message_compressed, message, exception_compressed, exception
    FROM logs
    WHERE Id >= 5519694 
    ORDER BY Id
)
UPDATE  cte
SET     message_compressed = COMPRESS(message), exception_compressed = COMPRESS(exception)

আরও তথ্যের জন্য এখানে দেখুন: এমএস এসকিউএল ব্যবহার করে কীভাবে আপডেট এবং অর্ডার করবেন


0

একটি পয়েন্ট এখনও নির্দেশিত না, গতি হয় । আমি জানি এটি একটি পুরানো উত্তরযুক্ত প্রশ্ন, তবে আমি মনে করি এটি সরাসরি মন্তব্য / উত্তরের যোগ্য:

এগুলি উত্সাহিত টেবিলগুলির সাথে একইভাবে করা যেতে পারে বলে মনে হয় red

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


-4
 ;with cte as
  (
  Select Department, Max(salary) as MaxSalary
  from test
  group by department
  )  
  select t.* from test t join cte c on c.department=t.department 
  where t.salary=c.MaxSalary;

এটা চেষ্টা কর

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.