Free tutorials & notes in Hindi & English · Clean code examples · Mobile friendly learning
MySQL + SQL · Lesson 78

MySQL में CTE और WITH Clause

Common Table Expression क्या है?

CTE one statement की duration के लिए query result को name देती है। Permanent database object बनाए बिना complex SQL को readable stages में बाँटा जा सकता है।

WITH cte_name AS (
  SELECT ...
)
SELECT ...
FROM cte_name;
Faculty rule: CTE का नाम rows के business meaning पर रखें—जैसे class_summary—temp1 जैसे vague sequence पर नहीं।

Verified Advanced Score Lab

CREATE TABLE advanced_scores (
  student_id INT PRIMARY KEY,
  student_name VARCHAR(60) NOT NULL,
  class_name VARCHAR(20) NOT NULL,
  marks DECIMAL(5,2) NOT NULL
);

INSERT INTO advanced_scores VALUES
(1, 'Aarav',  'X-A', 86),
(2, 'Meera',  'X-A', 92),
(3, 'Sana',   'X-A', 92),
(4, 'Kabir',  'X-B', 74),
(5, 'Vihaan', 'X-B', 88),
(6, 'Riya',   'X-B', 81);

X-A में three students, total 270, average 90। X-B में three students, total 243, average 81। यही checkpoints चारों Day 8 lessons verify करेंगे।

पहली CTE: Class Summary

WITH class_summary AS (
  SELECT class_name,
         COUNT(*) AS student_count,
         SUM(marks) AS total_marks,
         ROUND(AVG(marks), 2) AS average_marks
  FROM advanced_scores
  GROUP BY class_name
)
SELECT class_name, student_count,
       total_marks, average_marks
FROM class_summary
WHERE average_marks >= 85
ORDER BY class_name;
X-A | 3 | 270.00 | 90.00

CTE two summary rows बनाती है। Outer query X-A रखती है क्योंकि average 85 meet करती है; X-B at 81 नहीं। CTE display order guarantee नहीं करती, इसलिए presentation order के लिए final result में ORDER BY दें।

Multiple CTEs की Query Pipeline

WITH
class_summary AS (
  SELECT class_name, AVG(marks) AS class_average
  FROM advanced_scores
  GROUP BY class_name
),
above_class_average AS (
  SELECT s.student_id, s.student_name,
         s.class_name, s.marks,
         cs.class_average
  FROM advanced_scores AS s
  JOIN class_summary AS cs
    ON cs.class_name = s.class_name
  WHERE s.marks > cs.class_average
)
SELECT student_name, class_name, marks,
       ROUND(class_average, 2) AS class_average
FROM above_class_average
ORDER BY class_name, student_id;
Meera | X-A | 92.00 | 90.00 Sana | X-A | 92.00 | 90.00 Vihaan | X-B | 88.00 | 81.00

Second CTE first को refer कर सकती है क्योंकि class_summary earlier है। One WITH clause लें और definitions commas से separate करें।

CTE Reuse और WITH के साथ DML

Containing statement में CTE several times reference हो सकती है। यह aggregation repeat किए बिना strongest और weakest class average compare करती है:

WITH class_summary AS (
  SELECT class_name, AVG(marks) AS average_marks
  FROM advanced_scores
  GROUP BY class_name
)
SELECT hi.class_name AS highest_class,
       lo.class_name AS lowest_class
FROM class_summary AS hi
CROSS JOIN class_summary AS lo
WHERE hi.average_marks = (
        SELECT MAX(average_marks) FROM class_summary
      )
  AND lo.average_marks = (
        SELECT MIN(average_marks) FROM class_summary
      );
X-A | X-B

MySQL supported SELECT, UPDATE और DELETE positions पर WITH allow करता है। Data-changing DML से पहले CTE-driven row set को SELECT से preview करें और appropriate transaction लें।

CTE, Derived Table, View या Temporary Table?

ConstructLifetimeBest use
CTEOne statementReadable named stages और recursion
Derived tableOne query-block referenceSmall inline intermediate result
ViewPersistent schema objectReusable governed query interface
Temporary tableSessionMulti-statement staging और indexing

Scope, reuse, permissions और performance से चुनें—किसी one construct को universally superior न मानें।

Scope, Column Names और Dependencies

  • One WITH clause में CTE names unique हों।
  • CTE earlier CTEs को refer कर सकती है, same level पर later ones को नहीं।
  • Explicit column-name list result column count से match करे।
  • Explicit list न हो तो names CTE select list से आते हैं।
  • Base-table name को CTE name की तरह तभी reuse करें जब deliberate shadowing unmistakable हो।
WITH class_summary
     (class_name, student_count, average_marks) AS (
  SELECT class_name, COUNT(*), AVG(marks)
  FROM advanced_scores
  GROUP BY class_name
)
SELECT * FROM class_summary;

Optimizer Behavior और अभ्यास

Nonrecursive CTE outer query में merge या materialize हो सकती है। Materialized और multiple references होने पर MySQL query के लिए once materialize करके useful internal indexes add कर सकता है। Recursive CTE materialized होती है।

  1. हर CTE body independently validate करें।
  2. हर stage पर row grain और counts जाँचें।
  3. Semantics same रहें तभी early filter करें।
  4. EXPLAIN लें; CTE syntax speed promise नहीं करती।
  5. Representative data measure और wide intermediate results monitor करें।

अभ्यास: class maximum CTE; उससे top scorers; one summary CTE twice reference; basic example को derived table में rewrite करके plans compare करें।

Official संदर्भ

Syntax और behavior official MySQL 8.4 manual से जाँचे गए हैं। Production से पहले अपने server पर plans और limits verify करें।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

MySQL में CTE क्या है?
Common table expression WITH से defined, one SQL statement तक scoped named temporary result set है।
क्या CTE permanent table बनाती है?
नहीं। यह केवल statement तक रहती है। Result को बाद में भी रखना हो तो view या temporary/base table लें।
क्या one CTE दूसरी CTE को refer कर सकती है?
हाँ, same WITH clause में earlier-defined CTE को refer कर सकती है। Forward और mutually recursive references permitted नहीं हैं।
क्या same CTE multiple times reference हो सकती है?
हाँ। Same statement में reuse, repeated derived-table definition के मुकाबले readability advantage है।
क्या CTE हमेशा materialized और faster होती है?
नहीं। Nonrecursive CTE optimizer rules से merge या materialize हो सकती है। Recursive CTE materialized होती है। Actual plan measure करें।
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 लाइव कोड एडिटर

इस पेज के प्रोग्राम यहीं तैयार हैं — चलाएँ, बदलें और सीखें। कुछ भी इंस्टॉल किए बिना।
OneCompiler द्वारा संचालित। कोड एडिटर में अपने आप आ जाता है — Run दबाकर आउटपुट देखें। अगर एडिटर न खुले तो नए टैब में खोलें.