মূল কন্টেন্টে যান
মডিউল 7 · 1-এর পাঠ 4কোর্সে 25/57~12 min
মডিউল পাঠ (1/4)

CTE: WITH-এর সাথে বহু-পদক্ষেপের প্রশ্ন

প্রকৃত প্রশ্নগুলি বাড়তে থাকে: তিনটি JOINs, একটি GROUP BY, একটি সাবকোয়েরি, আরেকটি সাবকোয়ারি… এবং সেগুলি অপঠনযোগ্য হয়ে ওঠে। CTEs ("সাধারণ টেবিল অভিব্যক্তি", WITH ধারা) আপনাকে একটি নাম দিতে দেয় মধ্যবর্তী ধাপ এবং এটি ব্যবহার করুন যেন এটি মূল ক্যোয়ারীতে একটি টেবিল।

মৌলিক সিনট্যাক্স

SQL
WITH nome_cte AS (
  SELECT …    -- query interna
)
SELECT …      -- query principale, usa nome_cte come fosse una tabella
FROM   nome_cte;

একটি CTE বৈধ শুধুমাত্র এটি অনুসরণকারী প্রশ্নের জন্য: এটি টিকে থাকে না মৃত্যুদন্ড

উদাহরণ

3 জন গ্রাহককে খুঁজুন যারা সবচেয়ে বেশি খরচ করেছে (ডিলিভারি অর্ডারের পরিমাণ):

SQL
WITH total_spent AS (
  SELECT o.customer_id,
         SUM(oi.quantity * oi.unit_price) AS total
  FROM   orders      o
  JOIN   order_items oi ON oi.order_id = o.id
  WHERE  o.status = 'delivered'
  GROUP BY o.customer_id
)
SELECT c.email,
       s.total
FROM   total_spent s
JOIN   customers c ON c.id = s.customer_id
ORDER BY s.total DESC
LIMIT  3;

ইংরেজিতে পড়ুন: "প্রথমে গ্রাহক প্রতি খরচ গণনা করুন; তারপর যোগ দিন গ্রাহকরা এবং শীর্ষ 3" নিন। একটি CTE ছাড়া আপনার একটি ইনলাইন প্রয়োজন হবে FROM-এ সাবকোয়ারি (আইনি, কিন্তু শোরগোল)।

ক্যাসকেডে একাধিক CTE

আপনি কমা দ্বারা পৃথক একাধিক CTE সংজ্ঞায়িত করতে পারেন, এবং প্রতিটি উল্লেখ করতে পারেন আগেরগুলোর কাছে:

SQL
WITH total_spent AS (
  SELECT customer_id, SUM(quantity * unit_price) AS total
  FROM   order_items oi
  JOIN   orders      o ON oi.order_id = o.id
  WHERE  o.status = 'delivered'
  GROUP BY customer_id
),
average AS (
  SELECT AVG(total) AS total_average
  FROM   total_spent
)
SELECT c.email, s.total
FROM   total_spent s
JOIN   customers c ON c.id = s.customer_id
CROSS JOIN average
WHERE  s.total > average.total_average
ORDER BY s.total DESC;

CROSS JOIN average কারণ average সবসময় একটি সারি থাকে: কার্টেসিয়ান পণ্যটি ফলাফলের প্রতিটি সারিতে total_average যোগ করে।

CTE বনাম সাবকোয়েরি: কখন ব্যবহার করতে হবে

CTE গুলি উজ্জ্বল হয় যখন:

  • মূল ক্যোয়ারীতে একই সাবকোয়েরি দুই বা তার বেশি বার ব্যবহার করা হয়েছে;
  • আপনি কাঠামোকে নামযুক্ত ধাপে স্পষ্ট করতে চান (স্ব-নথিপত্রকরণ);
  • তারা পুনরাবৃত্ত CTEs এর জন্য পূর্বশর্ত (WITH RECURSIVE, এই মডিউলের পরবর্তী পাঠ)।

একটি ইনলাইন সাবকোয়ারি শুধুমাত্র একবার ব্যবহৃত একটি ধাপের জন্য আরও সংক্ষিপ্ত।

চেষ্টা করে দেখুন

ব্যায়াম#sql.m7.l1.e1
প্রচেষ্টা: 0লোড হচ্ছে...

'total_spent' নামে একটি CTE ব্যবহার করুন যেটি গণনা করে, প্রতিটি গ্রাহকের জন্য, বিতরণ করা অর্ডারের মোট খরচ (SUM(পরিমাণ * ইউনিট_মূল্য))। তারপরে প্রধান ক্যোয়ারীতে শীর্ষ 3 ব্যয়কারীদের জন্য ইমেল এবং মোট দেখান। মোট অবরোহ অনুসারে অর্ডার করুন, সীমা 3 পর্যন্ত।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

CTE যোগফলের ভিতরে * একক_মূল্য। প্রধান প্রশ্নে আইডিতে গ্রাহকদের সাথে যোগ দিন।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

ব্যায়াম পর্যালোচনা করুন

ব্যায়াম#sql.m7.l1.e2
প্রচেষ্টা: 0লোড হচ্ছে...

আগের অনুশীলনের মতো একই 'total_spent' CTE। মূল ক্যোয়ারীতে সেই গ্রাহকদের জন্য ইমেল এবং মোট দেখান যাদের খরচ গড় খরচের বেশি (অন্তত একটি ডেলিভারি অর্ডার সহ সমস্ত গ্রাহক জুড়ে)। মোট অবরোহ অনুসারে অর্ডার করুন।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

যেখানে স্কেলার সাবকোয়েরি: total_spent থেকে AVG(মোট) নির্বাচন করুন।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ