Chapterبەش 9 · Lectureوانە 9.4

SQL Functions, Aggregates and GROUP BYکردارەکانی SQL، کردارەکانی کۆکردنەوە و ⁦GROUP BY⁩

Make SQL calculate: single-row functions for numbers (ROUND, POWER, MOD), text (UPPER, LENGTH and CHAR_LENGTH, SUBSTRING, INSTR, TRIM, CONCAT) and dates (YEAR, MONTHNAME, DAYNAME); the aggregate functions COUNT, SUM, AVG, MIN and MAX; GROUP BY for one answer per group, HAVING to keep or drop groups, and the order in which SQL reads a query — with the differences between MySQL, MariaDB and SQLite.

وا لە SQL بکە ژماردن بکات: بۆ ژمارە (ROUND، POWER، MOD)، دەق (UPPER، LENGTH و ⁦CHAR_LENGTH⁩، SUBSTRING، INSTR، TRIM، CONCAT) و بەروار (YEAR، MONTHNAME، DAYNAME)؛ COUNT، SUM، AVG، MIN و MAX؛ بۆ یەک وەڵام بۆ هەر گرووپێک، بۆ هێشتنەوە یان لابردنی گرووپەکان و ئەو ڕیزبەندییەی SQL پێ دەخوێنێتەوە — لەگەڵ جیاوازییەکانی نێوان MySQL، MariaDB و SQLite.

43 min read44 خولەک خوێندنەوە · 30 stepsهەنگاو

What you will learnچی فێر دەبیت

  • Tell single-row functions from aggregate functions, and say where each kind may be used.
  • Use numeric functions — ROUND with negative places, POWER, MOD, FLOOR and CEIL — in SELECT and UPDATE.
  • Use text functions, explain why LENGTH and CHAR_LENGTH differ for Kurdish text, and split an e-mail address with INSTR and SUBSTRING.
  • Take dates apart with YEAR, MONTH, DAY, MONTHNAME and DAYNAME, and use a date function in WHERE.
  • Predict COUNT(*), COUNT(column), COUNT(DISTINCT), SUM, AVG, MIN and MAX, also with NULLs, on text and dates, and when no row matches.
  • Group rows with GROUP BY, keep or drop groups with HAVING, and write queries that MySQL 8.4 accepts with ONLY_FULL_GROUP_BY.
  • Explain the logical order FROM, WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, LIMIT, and use it to find mistakes.
  • لە جیا بکەیتەوە و بڵێیت هەر جۆرێکیان لە کوێ بەکار دێت.
  • — ROUND بە شوێنی سالب، POWER، MOD، FLOOR و CEIL — لە SELECT و UPDATE بەکار بهێنیت.
  • بەکار بهێنیت، ڕوون بکەیتەوە بۆچی LENGTH و ⁦CHAR_LENGTH⁩ بۆ دەقی کوردی جیاوازن و بە INSTR و SUBSTRING لەت بکەیت.
  • بەروار بە YEAR، MONTH، DAY، MONTHNAME و DAYNAME بکەیتە بەش و بەروار لە WHERE بەکار بهێنیت.
  • پێشبینیی ⁦COUNT(*)⁩، ⁦COUNT(column)⁩، ⁦COUNT(DISTINCT)⁩، SUM، AVG، MIN و MAX بکەیت، لەگەڵ NULL، لەسەر دەق و بەروار و کاتێک هیچ یەک ناگرێتەوە.
  • بە ⁦GROUP BY⁩ گرووپ بکەیت، گرووپەکان بە HAVING بهێڵیتەوە یان لایان ببەیت و بنووسیت کە ⁦MySQL 8.4⁩ لەگەڵ ⁦ONLY_FULL_GROUP_BY⁩ وەری بگرێت.
  • ڕیزبەندیی لۆجیکیی FROM، WHERE، ⁦GROUP BY⁩، HAVING، SELECT، DISTINCT، ⁦ORDER BY⁩، LIMIT ڕوون بکەیتەوە و بۆ دۆزینەوەی هەڵە بەکاری بهێنیت.

SQL functions: two kindsکردارەکانی SQL: دوو جۆر

An SQL does one job and gives back a value — exactly the idea of a function in PHP (what is a function?). MySQL has hundreds of . You call one by its name with its arguments in brackets: ROUND(2912.564, 1) gives 2912.6.

SQL یەک کار دەکات و نرخێک دەگەڕێنێتەوە — ڕێک هەمان بیرۆکەی لە PHP (کردار چییە؟). MySQL سەدان هەیە. بە ناوەکەی و لە ناو کەوانەدا بانگی دەکەیت: ROUND(2912.564, 1) 2912.6 دەدات.

All examples run on the shop database of the previous lesson (our example: a phone and computer shop). When MySQL and SQLite give different answers, both are shown.

هەموو نموونەکان لەسەر دوکانەکەی وانەی پێشوو جێبەجێ دەکرێن (نموونەکەمان: دوکانێکی مۆبایل و کۆمپیوتەر). هەر کاتێک MySQL و SQLite وەڵامی جیاواز بدەن، هەردووکیان پیشان دەدرێن.

SQL functions come in two kinds, and the difference is about how many rows go in:

SQL دوو جۆرن و جیاوازییەکەیان لە ژمارەی ئەو کە دەچنە ناویانەوە:

  • A works on one row at a time and gives one result for every row: UPPER(name) turns every name into capitals. There are three groups: numeric, text and date functions.
  • An takes many rows and gives one result: MAX(price_iqd) reads every price and answers with the largest. With GROUP BY it gives one result per group.
  • هەر جارە لەسەر یەک کار دەکات و بۆ هەموو یەک ئەنجام دەدات: UPPER(name) هەموو ناوێک دەکاتە پیتی گەورە. سێ گرووپی هەیە: ژمارەیی، دەقی و بەروار.
  • چەندین وەردەگرێت و یەک ئەنجام دەدات: MAX(price_iqd) هەموو قیمەتێک دەخوێنێتەوە و بە گەورەترینیان وەڵام دەداتەوە. لەگەڵ GROUP BY بۆ هەر گرووپێک یەک ئەنجام دەدات.
Two diagrams side by side. Left, a single-row function: four rows of the name column (Aram, Shilan, Karwan, Dilan) each go through UPPER() and come out as four rows (ARAM, SHILAN, KARWAN, DILAN) — four rows in, four results out. Right, an aggregate function: four prices (250000, 165000, 285000, 1350000) all flow into one MAX() box and one value comes out, 1350000 — four rows in, one result out.دوو هێڵکاری لە تەنیشت یەکتر. چەپ، کرداری تاکڕیز: چوار تۆماری ستوونی name (Aram، Shilan، Karwan، Dilan) هەر یەکەیان بە ناو UPPER()دا تێدەپەڕن و وەک چوار تۆمار دەردەچن (ARAM، SHILAN، KARWAN، DILAN) — چوار تۆمار دەچێتە ژوورەوە، چوار ئەنجام دەردەچێت. ڕاست، کرداری کۆکردنەوە: چوار قیمەت (250000، 165000، 285000، 1350000) هەموویان دەچنە ناو یەک سندووقی MAX()ـەوە و یەک نرخ دەردەچێت، 1350000 — چوار تۆمار دەچێتە ژوورەوە، یەک ئەنجام دەردەچێت.
A single-row function keeps the number of rows; an aggregate function folds many rows into one value. ژمارەی وەک خۆی دەهێڵێتەوە؛ چەندین دەپێچێتەوە بۆ یەک نرخ.CêIT
Quick checkپشکنینی خێراSELECT UPPER(name) FROM customers; runs on the six customers. How many rows does the answer have?SELECT UPPER(name) FROM customers; لەسەر شەش کڕیارەکە جێبەجێ دەکرێت. وەڵامەکە چەند هەیە؟

SQL functions: two kindsکردارەکانی SQL: دوو جۆر

Where each kind can be usedهەر جۆرێک لە کوێ بەکار دێت

The two kinds differ in how many rows go in, how many results come out, and where in a query they may stand:

دوو جۆرەکە لەمانەدا جیاوازن: چەند دەچێتە ناویان، چەند ئەنجام دەردەچێت و لە کوێی دەتوانن بێن:

The two kinds of SQL functionدوو جۆرەکەی SQL
Single-row (scalar) functionAggregate (multiple-row) function
Works onکار دەکات لەسەرone row at a timeهەر جارە یەک a group of rows (the whole table if there is no GROUP BY)گرووپێک (هەموو ئەگەر ⁦GROUP BY⁩ نەبێت)
Givesدەداتone result per rowیەک ئەنجام بۆ هەر one result per groupیەک ئەنجام بۆ هەر گرووپێک
Can be used inلە کوێ بەکار دێتSELECT, WHERE, ORDER BY (and GROUP BY)SELECT, HAVING, ORDER BY
ExamplesنموونەROUND, UPPER, SUBSTRING, YEAR, DAYNAMECOUNT, SUM, AVG, MIN, MAX
Quick checkپشکنینی خێراIn which part of a query can an aggregate such as COUNT(*) not be used?لە کام بەشی وەک COUNT(*) بەکار نایەت؟

Numeric functionsکردارە ژمارەییەکان

Numeric functions (answers from the MySQL 8.4 manual's rules) (وەڵامەکان بەپێی یاساکانی ڕێبەری ⁦MySQL 8.4⁩)
FunctionWhat it doesچی دەکاتExampleنموونەMySQL answerوەڵامی MySQL
ROUND(n, d)rounds n to d decimal places; without d, to a whole numbern بۆ d شوێنی دوای خاڵ خڕ دەکاتەوە؛ بەبێ d بۆ ROUND(2912.564, 1)2912.6
d may be negative: −1 rounds to tens, −3 to thousandsd دەکرێت سالب بێت: ⁦−1⁩ بۆ دەیان خڕ دەکاتەوە، ⁦−3⁩ بۆ هەزارانROUND(342.9234, -1)340
POWER(x, y), POW(x, y)x to the power y: xyx^yx بە y: xyx^yPOWER(2, 3)8
MOD(a, b), a % bthe remainder of a÷ba \div b () a÷ba \div bMOD(21, 2)1
ABS(x)the value without its minus signنرخەکە بەبێ نیشانەی کەمABS(-7500)7500
CEIL(x), FLOOR(x)the next whole number up / down دواتر بەرەو سەرەوە / خوارەوەCEIL(4.2), FLOOR(4.8)5, 4
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT ROUND(342.9234, -1), ROUND(2912.564, 1), ROUND(283.2),
       POWER(2, 3), MOD(21, 2), 21 % 2;

A negative number of places rounds to the left of the point: -1 to the nearest ten, -2 to the nearest hundred, -3 to the nearest thousand. For exact numbers MySQL rounds a half away from zero: ROUND(18750, -3) is 19000.

ئەگەر ژمارەی شوێنەکان سالب بێت، بۆ لای چەپی خاڵەکە خڕ دەکاتەوە: -1 بۆ نزیکترین دە، -2 بۆ نزیکترین سەد، -3 بۆ نزیکترین هەزار. بۆ ژمارە وردەکان MySQL نیوە بە دوور لە سفر خڕ دەکاتەوە: ROUND(18750, -3) دەبێتە 19000.

Quick checkپشکنینی خێراWhat does MySQL return for ROUND(1350000 * 1.1, -3)?MySQL بۆ ROUND(1350000 * 1.1, -3) چی دەگەڕێنێتەوە؟

Numeric functionsکردارە ژمارەییەکان

Prices, instalments and UPDATEقیمەت، قیست و UPDATE

Shops in Kurdistan price in whole thousands of dinars. A 10 % price rise, rounded to the nearest thousand:

دوکانەکانی کوردستان بە هەزارانی تەواوی دینار قیمەت دادەنێن. بەرزکردنەوەی قیمەت بە ⁦10 %⁩، خڕکراوە بۆ نزیکترین هەزار:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name, price_iqd, ROUND(price_iqd * 1.1, -3) AS new_price
FROM products
WHERE category IN ('charger', 'headphones');

The same function can change stored data inside UPDATE. Try it on a copy first, so a mistake costs nothing:

هەمان دەتوانێت لە ناو UPDATE هەڵگیراو بگۆڕێت. سەرەتا لەسەر کۆپییەک تاقی بکەرەوە، بۆ ئەوەی هەڵەیەک هیچ زیانێکی نەبێت:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
CREATE TABLE products_copy AS SELECT * FROM products;   -- a copy to practise on

UPDATE products_copy
SET price_iqd = ROUND(price_iqd * 1.1, -3)
WHERE category = 'charger';

SELECT name, price_iqd FROM products_copy WHERE category = 'charger';
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 3-5

Without the WHERE every product would get the new price (UPDATE without WHERE).

بەبێ WHERE هەموو کاڵایەک قیمەتە نوێیەکە وەردەگرێت (UPDATE بەبێ WHERE).

MOD and FLOOR split a price into ten monthly instalments in whole thousands, plus the rest paid at once. A monthly payment is the price divided by 10, cut down to whole thousands — FLOOR(price_iqd / 10000) * 1000 — and what is left is MOD(price_iqd, 10000):

MOD و FLOOR قیمەتێک دابەش دەکەن بۆ دە قیستی مانگانە بە هەزارانی تەواو، لەگەڵ ئەوەی دەمێنێتەوە و یەکجار دەدرێت. قیستی مانگانە قیمەتەکەیە دابەش بە ⁦10⁩، کورتکراوە بۆ هەزارانی تەواو — FLOOR(price_iqd / 10000) * 1000 — و ئەوەی دەمێنێتەوە MOD(price_iqd, 10000)ـە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name, price_iqd,
       FLOOR(price_iqd / 10000) * 1000 AS monthly,
       MOD(price_iqd, 10000)          AS pay_now
FROM products
WHERE category = 'phone';
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 2-3

Check the Redmi 13C: 10×16,000+5,000=165,00010 \times 16{,}000 + 5{,}000 = 165{,}000.

⁦Redmi 13C⁩ بپشکنە: 10×16,000+5,000=165,00010 \times 16{,}000 + 5{,}000 = 165{,}000.

A seller's commission (2 % of what they sold, rounded to whole dinars) needs the prices of the sold products, so it is computed after GROUP BY and a join: see GROUP BY over a join.

کۆمیسیۆنی فرۆشیارێک (⁦2 %⁩ی ئەوەی فرۆشتوویەتی، خڕکراوە بۆ دیناری تەواو) پێویستی بە قیمەتی کاڵا فرۆشراوەکانە، بۆیە دوای GROUP BY و دەژمێردرێت: بڕوانە ⁦GROUP BY⁩ لەگەڵ لێکبەستن.

Quick checkپشکنینی خێراA tablet costs 437,000 IQD. What do FLOOR(437000 / 10000) * 1000 and MOD(437000, 10000) give? ⁦437,000⁩ دینارە. FLOOR(437000 / 10000) * 1000 و MOD(437000, 10000) چی دەدەن؟

Text functionsکردارە دەقییەکان

Text functions change, measure and cut . Positions in SQL start at 1, not 0.

دەگۆڕن، دەپێون و دەبڕن. شوێن لە SQLـدا لە 1ـەوە دەست پێدەکات، نەک 0.

Text functions in MySQL لە MySQL
FunctionWhat it doesچی دەکاتExampleنموونەAnswerوەڵام
UPPER(s), UCASE(s)capital lettersپیتی گەورەUPPER('Hana')HANA
LOWER(s), LCASE(s)small lettersپیتی بچووکLOWER('Erbil')erbil
SUBSTRING(s, pos, n)n characters from position pos (also SUBSTR, MID); without n, to the endn لە شوێنی posـەوە (هەروەها SUBSTR، MID)؛ بەبێ n تا کۆتاییSUBSTRING('Redmi Note 13', 7, 4)Note
LEFT(s, n), RIGHT(s, n)the first / last n charactersیەکەم / دوایین n LEFT('Redmi Note 13', 5)Redmi
INSTR(s, part)the position where part first appears; 0 if it is not thereئەو شوێنەی part یەکەم جار تێیدا دەردەکەوێت؛ 0 ئەگەر نەبێتINSTR('Redmi Note 13', 'Note')7
TRIM(s), LTRIM(s), RTRIM(s)remove spaces at both ends / the left / the rightبۆشایی لە هەردوو سەر / چەپ / ڕاست لادەباتTRIM(' Erbil ')Erbil
LENGTH(s), CHAR_LENGTH(s)the length in bytes / in charactersدرێژی بە / بە CHAR_LENGTH('Hana')4
CONCAT(a, b, …)joins texts end to end ()دەقەکان بە دوای یەکدا دەلکێنێت ()CONCAT('Aram', ' (', 'Sulaimani', ')')Aram (Sulaimani)
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name, UPPER(name), LOWER(city)
FROM customers
WHERE customer_id <= 3;
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT SUBSTRING('Redmi Note 13', 7, 4), MID('Redmi Note 13', 7),
       LEFT('Redmi Note 13', 5), RIGHT('Redmi Note 13', 2);
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT INSTR('Redmi Note 13', 'Note'), INSTR('Redmi Note 13', 'Pro');
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

0 means not found. In MySQL INSTR ignores letter case with the default collation; in SQLite it does not (INSTR('Redmi Note 13', 'note') is 0 there).

0 واتە نەدۆزرایەوە. لە MySQL INSTR بە بنەڕەتی گەورە و بچووکیی پیت پشتگوێ دەخات؛ لە SQLite نا (INSTR('Redmi Note 13', 'note') لەوێ 0ـە).

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT LENGTH('  Erbil '), LENGTH(TRIM('  Erbil ')),
       LENGTH(LTRIM('  Erbil ')), LENGTH(RTRIM('  Erbil '));
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1-2

Two spaces in front and one behind: 8 characters, 5 after TRIM, 6 after LTRIM, 7 after RTRIM.

دوو بۆشایی لە پێشەوە و یەک لە دواوە: 8 ، 5 دوای TRIM، 6 دوای LTRIM، 7 دوای RTRIM.

CONCAT builds new text from columns. Careful with NULL: in MySQL one NULL argument makes the whole result NULL.

CONCAT لە دەقی نوێ دروست دەکات. ئاگاداری NULL بە: لە MySQL یەک NULL هەموو ئەنجامەکە دەکاتە NULL.

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name,
       CONCAT(name, ' (', city, ')') AS label,
       CONCAT(name, ' <', email, '>') AS contact
FROM customers
WHERE customer_id IN (1, 6);
Quick checkپشکنینی خێراWhat does SUBSTRING('Sulaimani', 1, 4) return?SUBSTRING('Sulaimani', 1, 4) چی دەگەڕێنێتەوە؟

String Functions in MySQL | Intermediate MySQL SeriesAlex The Analyst · Englishئینگلیزی · 230K viewsبینین · 3.8K likesلایک

MySQL text functions one by one: LENGTH, UPPER and LOWER, TRIM, LEFT and RIGHT, SUBSTRING, REPLACE, LOCATE and CONCAT.

یەک بە یەک: LENGTH، UPPER و LOWER، TRIM، LEFT و RIGHT، SUBSTRING، REPLACE، LOCATE و CONCAT.

Whole video, MySQL Workbench: LENGTH 0:20, UPPER/LOWER 1:48, TRIM 3:01, LEFT/RIGHT 4:22, SUBSTRING 6:25, REPLACE 8:14, LOCATE 9:10, CONCAT 10:18. For Kurdish text use CHAR_LENGTH (next screen).

هەموو ڤیدیۆکە، لە Workbench: LENGTH لە ⁦0:20⁩، UPPER/LOWER لە ⁦1:48⁩، TRIM لە ⁦3:01⁩، LEFT/RIGHT لە ⁦4:22⁩، SUBSTRING لە ⁦6:25⁩، REPLACE لە ⁦8:14⁩، LOCATE لە ⁦9:10⁩ و CONCAT لە ⁦10:18⁩. بۆ دەقی کوردی CHAR_LENGTH بەکاربهێنە (بەشی داهاتوو).

Text functionsکردارە دەقییەکان

LENGTH or CHAR_LENGTH? Kurdish textLENGTH یان ⁦CHAR_LENGTH⁩؟ دەقی کوردی

The textbook says LENGTH returns the number of characters. That is only true for English letters. MySQL stores text as UTF-8 (), where an English letter takes one byte but a Kurdish (Arabic-script) letter takes two (UTF-8: one to four bytes). LENGTH counts bytes; CHAR_LENGTH counts characters:

کتێبەکە دەڵێت LENGTH ژمارەی دەگەڕێنێتەوە. ئەمە تەنها بۆ پیتی ئینگلیزی ڕاستە. MySQL دەق بە ⁦UTF-8⁩ () هەڵدەگرێت کە تێیدا پیتێکی ئینگلیزی یەک دەگرێت، بەڵام پیتێکی کوردی (بە ئەلفوبێی عەرەبی) دوو (⁦UTF-8⁩: یەک تا چوار بایت). LENGTH دەژمێرێت؛ CHAR_LENGTH :

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT LENGTH('Shilan'), CHAR_LENGTH('Shilan'),
       LENGTH('شیلان'), CHAR_LENGTH('شیلان');

شیلان has five letters, and each is stored in two bytes, so LENGTH says 10. Use CHAR_LENGTH whenever you mean how many letters — for example to check that a name is not longer than its VARCHAR(40) column, because VARCHAR(n) also counts characters.

شیلان پێنج پیتە و هەر پیتێک لە دوو هەڵدەگیرێت، بۆیە LENGTH دەڵێت ⁦10⁩. هەر کاتێک مەبەستت چەند پیتـە CHAR_LENGTH بەکار بهێنە — بۆ نموونە بۆ پشکنینی ئەوەی ناوێک لە VARCHAR(40)ـەکەی درێژتر نییە، چونکە VARCHAR(n)ـیش دەژمێرێت.

Quick checkپشکنینی خێراHow many bytes does LENGTH('دیلان') return in MySQL (UTF-8)?LENGTH('دیلان') لە ⁦MySQL (UTF-8)⁩ چەند دەگەڕێنێتەوە؟

Text functionsکردارە دەقییەکان

Splitting an e-mail addressلەتکردنی ناونیشانێکی ئیمەیڵ

INSTR finds where the @ is; LEFT and SUBSTRING cut before and after it. The user name is everything before the @ (position − 1 characters); the domain starts one position after it:

INSTR شوێنی @ دەدۆزێتەوە؛ LEFT و SUBSTRING پێش و دوای ئەو دەبڕن. هەموو ئەوەیە کە پێش @ دێت (شوێن − 1 )؛ دۆمەین یەک شوێن دوای ئەو دەست پێدەکات:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT email,
       LEFT(email, INSTR(email, '@') - 1)   AS user_name,
       SUBSTRING(email, INSTR(email, '@') + 1) AS domain
FROM customers;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 6

Soran has no e-mail: every function of NULL gives NULL.

Soran نییە: هەر کە NULL وەربگرێت NULL دەدات.

TRIM can also remove a given text from one end. The textbook removes .com from e-mails; in MySQL that is TRIM(TRAILING '.com' FROM email):

TRIM دەتوانێت دەقێکی دیاریکراویش لە سەرێک لابەرێت. کتێبەکە ⁦.com⁩ لە ئیمەیڵەکان لادەبات؛ لە MySQL ئەوە TRIM(TRAILING '.com' FROM email)ـە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT email, TRIM(TRAILING '.com' FROM email) AS without_com
FROM customers
WHERE customer_id <= 3;

Text functions also work in WHERE. The textbook's two activities, on our shop: brands that start with S in capitals, and the first ten characters of every long product name.

لە WHEREـیش کار دەکەن. دوو چالاکییەکەی کتێبەکە، لەسەر دوکانەکەمان: ئەو براندانەی بە S دەست پێدەکەن بە پیتی گەورە و یەکەم دە هەموو ناوێکی درێژی کاڵا.

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT UPPER(brand) AS brand, name FROM products WHERE brand LIKE 'S%';
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name, SUBSTRING(name, 1, 10) AS short_name
FROM products
WHERE CHAR_LENGTH(name) > 15;
Quick checkپشکنینی خێراFor karwan88@example.com, what does INSTR(email, '@') return?بۆ karwan88@example.com، INSTR(email, '@') چی دەگەڕێنێتەوە؟

Date functionsکردارەکانی بەروار

Date functions read the clock or take a date apart. They return numbers (the year 2026), text (October) or a new date.

بەروار کاتژمێر دەخوێننەوە یان بەروارێک دەکەنە بەش. ژمارە (ساڵی ⁦2026⁩)، دەق (October) یان بەرواری نوێ دەگەڕێننەوە.

Date functions in MySQL (answers from the MySQL 8.4 manual's rules; the weekdays were checked with Python) بەروار لە MySQL (وەڵامەکان بەپێی ڕێبەری ⁦MySQL 8.4⁩؛ ڕۆژەکانی هەفتە بە Python پشکنراون)
FunctionGivesدەداتExampleنموونەMySQL answerوەڵامی MySQL
NOW()the date and time now (server clock)بەروار و کاتی ئێستا (کاتژمێری )NOW()e.g. 2026-10-25 and the timeبۆ نموونە ⁦2026-10-25⁩ و کاتەکە
CURDATE()today's dateبەرواری ئەمڕۆCURDATE()2026-10-25 (on that day)⁦2026-10-25⁩ (لەو ڕۆژەدا)
DATE(x)the date part of a date and timeبەشی بەرواری بەروار و کاتێکDATE('2026-10-24 18:05:00')2026-10-24
YEAR(d), MONTH(d), DAY(d)the year, month and day as numbersساڵ، مانگ و ڕۆژ وەک ژمارەMONTH('2026-10-09')10
MONTHNAME(d)the name of the monthناوی مانگەکەMONTHNAME('2026-10-09')October
DAYNAME(d)the name of the weekdayناوی ڕۆژی هەفتەDAYNAME('2026-10-09')Friday
DAYOFWEEK(d)weekday as a number: 1 = Sunday … 7 = Saturdayڕۆژی هەفتە وەک ژمارە: 1 = یەکشەممە … 7 = شەممەDAYOFWEEK('2026-10-09')6
DATE_FORMAT(d, f)the date as text in a patternبەروارەکە وەک دەق بە شێوەیەکی دیاریکراوDATE_FORMAT('2026-10-09', '%W, %e %M %Y')Friday, 9 October 2026
DATEDIFF(a, b)the number of days from b to aژمارەی ڕۆژەکان لە bـەوە تا aDATEDIFF('2026-10-25', '2026-09-02')53

The day, month and year of three sales (the textbook asks the same about the day each employee joined):

ڕۆژ، مانگ و ساڵی سێ فرۆشتن (کتێبەکە هەمان پرسیار دەربارەی ئەو ڕۆژە دەکات کە هەر فەرمانبەرێک دەستی بە کار کردووە):

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT sold_on, YEAR(sold_on), MONTH(sold_on), DAY(sold_on),
       MONTHNAME(sold_on), DAYNAME(sold_on)
FROM sales
WHERE sale_id IN (1, 13, 20);

Date functionsکردارەکانی بەروار

The weekend: DAYNAME in WHEREپشووی کۆتایی هەفتە: DAYNAME لە WHERE

A single-row function can be used inside WHERE. In Kurdistan, Friday is the main day off of the week, so the owner wants to know which sales happened on a Friday:

دەتوانرێت لە ناو WHERE بەکار بهێنرێت. لە کوردستان هەینی ڕۆژی سەرەکیی پشووی هەفتەیە، بۆیە خاوەنی دوکانەکە دەیەوێت بزانێت کام فرۆشتن لە ڕۆژی هەینیدا بووە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT sale_id, sold_on, DAYNAME(sold_on) AS day
FROM sales
WHERE DAYNAME(sold_on) = 'Friday';

The other way round — every sale not on a Friday — is <>; 17 of the 20 sales. The textbook also shows such dates in a long form such as Wednesday, 2 September 2026; DATE_FORMAT does it in one step:

پێچەوانەکەی — هەموو فرۆشتنێک کە لە هەینیدا نەبووە — <>ـە؛ ⁦17⁩ لە ⁦20⁩ فرۆشتنەکە. کتێبەکە ئەم جۆرە بەروارانە بە شێوەیەکی درێژیش پیشان دەدات، وەک ⁦Wednesday, 2 September 2026⁩؛ DATE_FORMAT بە یەک هەنگاو ئەمە دەکات:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT COUNT(*) AS not_on_friday FROM sales WHERE DAYNAME(sold_on) <> 'Friday';
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT sale_id, DATE_FORMAT(sold_on, '%W, %e %M %Y') AS nice_date
FROM sales
WHERE sale_id IN (1, 13);
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

%W weekday name, %e day without a leading zero, %M month name, %Y four-digit year.

%W ناوی ڕۆژی هەفتە، %e ڕۆژ بەبێ سفری پێشەوە، %M ناوی مانگ، %Y ساڵی چوار ژمارەیی.

Quick checkپشکنینی خێراWhich condition finds the sales made in October, whatever the year?کام ئەو فرۆشتنانە دەدۆزێتەوە کە لە تشرینی یەکەمدا کراون، ساڵەکە هەرچی بێت؟

Aggregate functions: one answer from many rowsکردارەکانی کۆکردنەوە: یەک وەڵام لە چەندین تۆمار

Five answer the questions every shop owner asks: how many, how much in total, on average, the least, the most. Without GROUP BY they treat all the rows that pass WHERE as one group.

پێنج وەڵامی ئەو پرسیارانە دەدەنەوە کە هەموو خاوەن دوکانێک دەیانکات: چەند، کۆی گشتی چەند، بە تێکڕا، کەمترین، زۆرترین. بەبێ GROUP BY هەموو ئەو لە WHERE تێدەپەڕن وەک یەک گرووپ دادەنێن.

The five aggregate functions (MySQL 8.4 manual: aggregate functions ignore NULL unless stated otherwise)پێنج (ڕێبەری ⁦MySQL 8.4⁩: NULL پشتگوێ دەخەن مەگەر بە پێچەوانەوە وترابێت)
FunctionGivesدەداتNULL valuesنرخەکانی NULL
COUNT(*)the number of rowsژمارەی counted — it counts rows, not valuesدەژمێردرێن — دەژمێرێت، نەک نرخ
COUNT(column)the number of values in the columnژمارەی نرخەکانی ناو skippedپشتگوێ دەخرێن
COUNT(DISTINCT column)the number of different valuesژمارەی نرخە جیاوازەکانskippedپشتگوێ دەخرێن
SUM(column)the total (numbers only)کۆی گشتی (تەنها ژمارە)skippedپشتگوێ دەخرێن
AVG(column)the average, the arithmetic (numbers only)تێکڕا، واتە ژمێرەیی (تەنها ژمارە)skipped — not counted as 0پشتگوێ دەخرێن — وەک 0 هەژمار ناکرێن
MIN(column), MAX(column)the smallest / largest — numbers, text or datesبچووکترین / گەورەترین — ژمارە، دەق یان بەروارskippedپشتگوێ دەخرێن
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT COUNT(*), COUNT(email), COUNT(DISTINCT city) FROM customers;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

6 customers; 5 e-mail addresses, because Soran's is NULL; 5 cities, because Aram and Dilan both live in Sulaimani.

6 کڕیار؛ 5 ، چونکە هی Soran NULLـە؛ 5 شار، چونکە Aram و Dilan هەردووکیان لە سلێمانی دەژین.

The total, the average, the cheapest and the dearest of the four phones:

کۆ، تێکڕا، هەرزانترین و گرانترینی چوار مۆبایلەکە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT SUM(price_iqd), AVG(price_iqd), MIN(price_iqd), MAX(price_iqd)
FROM products
WHERE category = 'phone';
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

MySQL returns AVG (and SUM) of whole numbers as an exact DECIMAL; the average shows four decimal places. SQLite returns a decimal fraction (a float).

MySQL AVG (و SUM)ی وەک DECIMALـێکی ورد دەگەڕێنێتەوە؛ تێکڕاکە چوار شوێنی دوای خاڵ پیشان دەدات. SQLite دەگەڕێنێتەوە.

Quick checkپشکنینی خێراThe customers table has 6 rows and one NULL e-mail. What is COUNT(*) - COUNT(email)? customers 6 هەیە و یەک NULL. COUNT(*) - COUNT(email) چەندە؟

فێرکاری SQL - سەرەتاییRawan :: ڕەوان · Kurdish (Sorani)کوردی (سۆرانی) · 16K viewsبینین · 488 likesلایک · Partبەشی 18:55–20:45 (ofلە 21:38)

In Kurdish: how to add, read, filter, change and delete rows with INSERT, SELECT, WHERE, UPDATE and DELETE.

بە کوردی فێر دەبیت چۆن زیاد دەکەیت، دەخوێنیتەوە، دەکەیت، دەگۆڕیت و دەسڕیتەوە بە ، ، ، و .

Kurdish (Sorani). Plays 18:55-20:45 (Aggregate Functions): a slide of the five functions in Kurdish, then COUNT and GROUP BY; frames checked.

بە کوردیی سۆرانی، لە ⁦18:55⁩ تا ⁦20:45⁩ پەخش دەبێت (بەشی Aggregate Functions): بە کوردی دەربارەی پێنج ، پاشان COUNT و .

Aggregate functions: one answer from many rowsکردارەکانی کۆکردنەوە: یەک وەڵام لە چەندین تۆمار

AVG and NULL, and naming an aggregateAVG و NULL و ناونانی کردارێکی کۆکردنەوە

AVG is the arithmetic mean you know from statistics (the mean of ungrouped data). It divides by the number of values, not rows. The laptops have stocks 4, NULL and 5:

AVG هەمان ژمێرەییە کە لە ئامارەوە دەیناسیت (ناوەندی داتای گرووپنەکراو). دابەشی ژمارەی نرخەکان دەکات، نەک . کۆگایان 4، NULL و 5ـە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT SUM(stock), AVG(stock), COUNT(stock), COUNT(*)
FROM products
WHERE category = 'laptop';
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

(4+5)÷2=4.5(4 + 5) \div 2 = 4.5. If the unknown stock were counted as 0, the average would be (4+0+5)÷3=3(4 + 0 + 5) \div 3 = 3 — a different answer.

(4+5)÷2=4.5(4 + 5) \div 2 = 4.5. ئەگەر کۆگا نەزانراوەکە وەک 0 هەژمار بکرایە، تێکڕاکە دەبووە (4+0+5)÷3=3(4 + 0 + 5) \div 3 = 3 — وەڵامێکی جیاواز.

An aggregate can be combined with WHERE, and its column can get an alias. How many Samsung products are there, and what do they cost at least and at most?

دەتوانرێت لەگەڵ WHERE تێکەڵ بکرێت و وەربگرێت. چەند کاڵای Samsung هەیە و کەمترین و زۆرترین قیمەتیان چەندە؟

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT COUNT(*) AS samsung_products, MIN(price_iqd), MAX(price_iqd)
FROM products
WHERE brand = 'Samsung';
Quick checkپشکنینی خێراA column holds 10, NULL, 20 and NULL. What does AVG give for it? نرخەکانی ⁦10⁩، NULL، ⁦20⁩ و NULLـی تێدایە. AVG چی بۆ دەدات؟

Aggregate functions: one answer from many rowsکردارەکانی کۆکردنەوە: یەک وەڵام لە چەندین تۆمار

MIN and MAX on text and datesMIN و MAX لەسەر دەق و بەروار

MIN and MAX compare any values that can be put in order: numbers by size, text alphabetically (by the ), dates by time. The first and last product name, and the oldest and newest product:

MIN و MAX هەر نرخێک بەراورد دەکەن کە بتوانرێت ڕیز بکرێت: ژمارە بەپێی قەبارە، دەق بەپێی ئەلفوبێ (بەپێی )، بەروار بەپێی کات. یەکەم و دوایین ناوی کاڵا و کۆنترین و نوێترین کاڵا:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT MIN(name), MAX(name), MIN(added_on), MAX(added_on) FROM products;

The same works on the sales: SELECT MIN(sold_on), MAX(sold_on) FROM sales; gives the first and the last day of sales, 2026-09-02 and 2026-10-24.

هەمان شت لەسەر فرۆشتنەکان کار دەکات: SELECT MIN(sold_on), MAX(sold_on) FROM sales; یەکەم و دوایین ڕۆژی فرۆشتن دەدات، 2026-09-02 و 2026-10-24.

Quick checkپشکنینی خێراWhat does SELECT MAX(city) FROM customers; return?SELECT MAX(city) FROM customers; چی دەگەڕێنێتەوە؟

Aggregate functions: one answer from many rowsکردارەکانی کۆکردنەوە: یەک وەڵام لە چەندین تۆمار

DISTINCT inside aggregates, and an empty resultDISTINCT لە ناو کردارەکانی کۆکردنەوەدا و ئەنجامی بەتاڵ

DISTINCT inside the brackets counts or adds every different value once. The 20 sales sold 27 items; the different quantities are 1, 2 and 3:

DISTINCT لە ناو کەوانەکاندا هەر نرخێکی جیاواز یەک جار دەژمێرێت یان کۆ دەکاتەوە. ⁦20⁩ فرۆشتنەکە ⁦27⁩ دانەیان فرۆشتووە؛ بڕە جیاوازەکان 1، 2 و 3ـن:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT SUM(quantity), SUM(DISTINCT quantity), COUNT(DISTINCT quantity)
FROM sales;

What happens when WHERE matches no row? Nobody paid by cheque:

چی ڕوودەدات کاتێک WHERE هیچ نادۆزێتەوە؟ کەس بە چەک پارەی نەداوە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT COUNT(*), SUM(quantity), AVG(quantity), MAX(sold_on)
FROM sales
WHERE payment = 'cheque';
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

COUNT of nothing is 0; SUM, AVG, MIN and MAX of nothing are NULL (there is no total, average or largest of nothing).

COUNTـی هیچ 0ـە؛ SUM، AVG، MIN و MAXـی هیچ NULLـن (هیچ کۆ، تێکڕا یان گەورەترینێک بۆ هیچ نییە).

In a report you usually want 0, not NULL. COALESCE gives it:

لە ڕاپۆرتدا زۆرجار 0ت دەوێت، نەک NULL. COALESCE ئەوە دەدات:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT COALESCE(SUM(quantity), 0) AS items FROM sales WHERE payment = 'cheque';
Quick checkپشکنینی خێراWhat does SELECT COUNT(*) FROM sales WHERE customer_id = 7; return? (There is no customer 7.)SELECT COUNT(*) FROM sales WHERE customer_id = 7; چی دەگەڕێنێتەوە؟ (کڕیاری 7 نییە.)

An aggregate next to a plain columnکردارێکی کۆکردنەوە لە تەنیشت ستوونێکی ئاسایی

What is the most expensive product, and what is it called? A natural first try mixes a plain column with an aggregate:

گرانترین کاڵا کامەیە و ناوی چییە؟ یەکەم هەوڵی سروشتی ئاسایی لەگەڵ تێکەڵ دەکات:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name, MAX(price_iqd) FROM products;

MAX folds 12 rows into one value, but name still has 12 values. Which one should the single answer row show? Standard SQL says: with an aggregate and no GROUP BY, every other column must be inside an aggregate too. The three databases you may meet react differently:

MAX ⁦12⁩ دەپێچێتەوە بۆ یەک نرخ، بەڵام name هێشتا ⁦12⁩ نرخی هەیە. یەک وەڵامەکە کامیان پیشان بدات؟ SQLـی ستاندارد دەڵێت: لەگەڵ و بەبێ GROUP BY، هەموو تر دەبێت ئەویش لە ناو بێت. ئەو سێ لەوانەیە بیانبینیت بە شێوەی جیاواز وەڵام دەدەنەوە:

SELECT name, MAX(price_iqd) FROM products; in three databases (MySQL and MariaDB from their manuals, SQLite run)⁦SELECT name, MAX(price_iqd) FROM products;⁩ لە سێ (MySQL و MariaDB لە ڕێبەرەکانیانەوە، SQLite جێبەجێ کراوە)
DatabaseWhat happensچی ڕوودەدات
MySQL 8.4Refused, because the SQL mode ONLY_FULL_GROUP_BY is on by default: ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'shop.products.name'; this is incompatible with sql_mode=only_full_group_byڕەت دەکرێتەوە، چونکە دۆخی SQLـی ONLY_FULL_GROUP_BY بە شێوەی بنەڕەتی چالاکە: ⁦ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'shop.products.name'; this is incompatible with sql_mode=only_full_group_by⁩
MariaDB (XAMPP)MariaDB (لە XAMPP)Accepted: ONLY_FULL_GROUP_BY is off by default. The name comes from an arbitrary row — not necessarily the iPhone. The answer looks right but may be wrong.وەردەگیرێت: ONLY_FULL_GROUP_BY بە شێوەی بنەڕەتی ناچالاکە. ناوەکە لە هەڕەمەکیـەوە دێت — نەک بە دڵنیاییەوە iPhone. وەڵامەکە ڕاست دەردەکەوێت بەڵام لەوانەیە هەڵە بێت.
SQLiteAccepted, with a special rule: when the query has exactly one MIN() or MAX(), the other columns come from the row that holds it. The answer below is SQLite's.وەردەگیرێت، بە یاسایەکی تایبەت: کاتێک ڕێک یەک MIN() یان MAX()ـی هەیە، تر لەو دێن کە ئەو نرخەی تێدایە. وەڵامی خوارەوە هی SQLiteـە.
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name, MAX(price_iqd) FROM products;   -- SQLite only
Quick checkپشکنینی خێراWhat does MySQL 8.4, with its default settings, do with SELECT name, MAX(price_iqd) FROM products;?⁦MySQL 8.4⁩ بە ڕێکخستنی بنەڕەتی چی لە SELECT name, MAX(price_iqd) FROM products; دەکات؟

An aggregate next to a plain columnکردارێکی کۆکردنەوە لە تەنیشت ستوونێکی ئاسایی

The portable answer: a subqueryوەڵامی گشتگیر: ژێرپرسێک

Do not depend on any of these. The portable answer asks two questions, one inside the other: first what is the highest price?, then which product has that price?. The inner SELECT in brackets is a :

پشت بە هیچیان مەبەستە. وەڵامی گشتگیر دوو پرسیار دەکات، یەکێکیان لە ناو ئەوی تردا: یەکەم بەرزترین قیمەت چەندە؟، پاشان کام کاڵا ئەو قیمەتەی هەیە؟. SELECTـی ناوەوە لە ناو کەوانەدا :

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name, price_iqd
FROM products
WHERE price_iqd = (SELECT MAX(price_iqd) FROM products);
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 3

The subquery runs first and gives 1350000; the outer query then finds every product with that price — all of them if two products share the top price.

یەکەم جێبەجێ دەکرێت و ⁦1350000⁩ دەدات؛ پاشان دەرەوە هەموو کاڵایەک بەو قیمەتە دەدۆزێتەوە — هەموویان ئەگەر دوو کاڵا هەمان بەرزترین قیمەتیان هەبێت.

Quick checkپشکنینی خێراYour query works in XAMPP's phpMyAdmin but fails on the school's MySQL 8.4 server with ERROR 1140. What is the best fix? لە phpMyAdminـی XAMPP کار دەکات بەڵام لەسەر ⁦MySQL 8.4⁩ـی قوتابخانە بە ⁦ERROR 1140⁩ هەڵە دەدات. چاکترین ڕێگا بۆ چارەسەرکردنی چییە؟

GROUP BY: one answer per group⁦GROUP BY⁩: یەک وەڵام بۆ هەر گرووپێک

How many products are there in each category? Without grouping you would need one query per category — WHERE category = 'phone', then 'laptop', and so on — and you would first have to know every category. does it in one query:

لە هەر جۆرێکدا چەند کاڵا هەیە؟ بەبێ گرووپکردن بۆ هەر جۆرێک پێویست دەبوو — WHERE category = 'phone'، پاشان 'laptop' و هتد — و دەبوو سەرەتا هەموو جۆرەکان بزانیت. بە یەک ئەمە دەکات:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category, COUNT(*) AS products,
       MIN(price_iqd) AS cheapest, MAX(price_iqd) AS dearest
FROM products
GROUP BY category
ORDER BY category;

SQL puts the rows with the same category into one group and runs every aggregate once per group: one answer row for each of the four categories.

SQL ئەو هەمان categoryـیان هەیە دەخاتە یەک گرووپ و هەموو بۆ هەر گرووپێک یەک جار جێبەجێ دەکات: یەک وەڵام بۆ هەر یەک لە چوار جۆرەکە.

Everyday analogyنموونەیەک لە ژیانی ڕۆژانەوە

At the end of the day the shop's receipts are sorted into three piles: cash, card and FIB. Then each pile is counted and its amounts added up. GROUP BY payment makes the piles; COUNT and SUM work on each pile.

لە کۆتایی ڕۆژدا پسوولەکانی دوکانەکە دەکرێنە سێ کۆمەڵ: نەختینە، کارت و FIB. پاشان هەر کۆمەڵێک دەژمێردرێت و پارەکەی کۆ دەکرێتەوە. GROUP BY payment کۆمەڵەکان دروست دەکات؛ COUNT و SUM لەسەر هەر کۆمەڵێک کار دەکەن.

Where the analogy stops workingسنووری ئەم نموونەیە

A person sorting receipts can glance at a pile and say these are mostly phones. SQL can only report what you ask for with an aggregate or with a column you grouped by.

کەسێک کە پسوولە ڕیز دەکات دەتوانێت سەیری کۆمەڵێک بکات و بڵێت زۆربەی ئەمانە مۆبایلن. SQL تەنها ئەوە ڕاپۆرت دەکات کە بە یان بە کە گرووپی پێ کردووە داوای دەکەیت.

The sales of each seller, and the number of sales of each payment type — the textbook's cars sold by each employee and payments per payment mode, on our shop:

فرۆشتنەکانی هەر فرۆشیارێک و ژمارەی فرۆشتنی هەر جۆرێکی پارەدان — ئۆتۆمبێلی فرۆشراو لەلایەن هەر فەرمانبەرێکەوە و پارەدان بەپێی جۆری پارەدانـی کتێبەکە، لەسەر دوکانەکەمان:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT seller, COUNT(*) AS sales, SUM(quantity) AS items
FROM sales
GROUP BY seller
ORDER BY seller;
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT payment, COUNT(*) AS sales
FROM sales
GROUP BY payment
ORDER BY payment;
Quick checkپشکنینی خێراHow many rows does SELECT payment, COUNT(*) FROM sales GROUP BY payment; return?SELECT payment, COUNT(*) FROM sales GROUP BY payment; چەند دەگەڕێنێتەوە؟

GROUP BY: one answer per group⁦GROUP BY⁩: یەک وەڵام بۆ هەر گرووپێک

The GROUP BY rule, and NULL as a groupیاسای ⁦GROUP BY⁩ و NULL وەک گرووپێک

NULLs form a group of their own: the power bank with no brand gets its own row (MySQL's manual: two NULL values are regarded as equal in a GROUP BY).

NULLـەکان گرووپێکی تایبەت بە خۆیان پێکدەهێنن: پاوەر بانکە بێ براندەکە تایبەت بە خۆی وەردەگرێت (ڕێبەری MySQL: دوو نرخی NULL لە ⁦GROUP BY⁩ـدا وەک یەکسان هەژمار دەکرێن).

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT brand, COUNT(*) AS products
FROM products
GROUP BY brand
ORDER BY brand;
Quick checkپشکنینی خێراWhich query is accepted by MySQL 8.4?کام لەلایەن ⁦MySQL 8.4⁩ـەوە وەردەگیرێت؟

GROUP BY: one answer per group⁦GROUP BY⁩: یەک وەڵام بۆ هەر گرووپێک

Grouping by monthگرووپکردن بەپێی مانگ

You can group by an expression, such as the month of a date. Sales and items per month:

دەتوانیت بەپێی گرووپ بکەیت، وەک مانگی بەروارێک. فرۆشتن و دانەکان بۆ هەر مانگێک:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT YEAR(sold_on) AS year, MONTHNAME(sold_on) AS month,
       COUNT(*) AS sales, SUM(quantity) AS items
FROM sales
GROUP BY YEAR(sold_on), MONTH(sold_on), MONTHNAME(sold_on)
ORDER BY YEAR(sold_on), MONTH(sold_on);
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 4

MONTH() keeps the months in calendar order; MONTHNAME() is grouped too, because it appears in SELECT. The year is part of the group, so October 2026 and October 2027 would stay apart.

MONTH() مانگەکان بە ڕیزبەندیی ساڵنامە دەهێڵێتەوە؛ MONTHNAME()ـیش گرووپ دەکرێت چونکە لە SELECTـدا دەردەکەوێت. ساڵەکە بەشێکە لە گرووپەکە، بۆیە تشرینی یەکەمی ⁦2026⁩ و تشرینی یەکەمی ⁦2027⁩ لە یەک جیا دەمێننەوە.

GROUP BY: one answer per group⁦GROUP BY⁩: یەک وەڵام بۆ هەر گرووپێک

GROUP BY over a join⁦GROUP BY⁩ لەسەر لێکبەستنێک

Brands and prices are in products, quantities in sales. An INNER JOIN puts each sale next to its product (joins); then GROUP BY works on the joined rows. AS s and AS p are short for the tables:

براند و قیمەت لە productsـدان، بڕەکان لە salesـدا. INNER JOIN هەر فرۆشتنێک لە تەنیشت کاڵاکەی دادەنێت (لێکبەستنەکان)؛ پاشان GROUP BY لەسەر کار دەکات. AS s و AS p کورتن بۆ :

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT p.brand, COUNT(*) AS sales, SUM(s.quantity) AS items_sold
FROM sales AS s
INNER JOIN products AS p ON s.product_id = p.product_id
GROUP BY p.brand
ORDER BY items_sold DESC, p.brand;
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT p.category, SUM(s.quantity * p.price_iqd) AS revenue_iqd
FROM sales AS s
INNER JOIN products AS p ON s.product_id = p.product_id
GROUP BY p.category
ORDER BY revenue_iqd DESC;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 1

The money of each sale is quantity × price; SUM adds it up per category. (This uses today's prices; a real shop also stores the price paid in sales.)

پارەی هەر فرۆشتنێک بڕ × قیمەتە؛ SUM بۆ هەر جۆرێک کۆی دەکاتەوە. (ئەمە قیمەتەکانی ئەمڕۆ بەکار دەهێنێت؛ دوکانێکی ڕاستەقینە قیمەتی دراویش لە salesـدا هەڵدەگرێت.)

Each seller earns a 2 % commission on what they sold, rounded to whole dinars — the textbook's commission example, now per seller:

هەر فرۆشیارێک ⁦2 %⁩ی ئەوەی فرۆشتوویەتی وەک کۆمیسیۆن وەردەگرێت، خڕکراوە بۆ دیناری تەواو — نموونەی کۆمیسیۆنی کتێبەکە، ئێستا بۆ هەر فرۆشیارێک:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT s.seller,
       SUM(s.quantity * p.price_iqd) AS sold_iqd,
       ROUND(SUM(s.quantity * p.price_iqd) * 0.02) AS commission
FROM sales AS s
INNER JOIN products AS p ON s.product_id = p.product_id
GROUP BY s.seller
ORDER BY s.seller;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 3

A single-row function (ROUND) around an aggregate (SUM): first the total per seller, then 2 %, then rounding.

(ROUND) بە دەوری (SUM): یەکەم کۆی هەر فرۆشیارێک، پاشان ⁦2 %⁩، پاشان خڕکردنەوە.

Quick checkپشکنینی خێراIn the brand query above, why is there a row whose brand is NULL?لە براندەکانی سەرەوە، بۆچی هەیە کە براندەکەی NULLـە؟

HAVING: keeping or dropping whole groupsHAVING: هێشتنەوە یان لابردنی گرووپی تەواو

WHERE filters rows before they are grouped. filters groups after GROUP BY, so it may use aggregates. The textbook's question which payment types were used more than twice? needs HAVING:

WHERE پێش گرووپکردن دەپاڵێوێت. دوای GROUP BY گرووپەکان دەپاڵێوێت، بۆیە دەتوانێت بەکار بهێنێت. پرسیاری کتێبەکە کام جۆری پارەدان زیاتر لە دوو جار بەکار هاتووە؟ پێویستی بە HAVINGـە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT payment, COUNT(*) AS times
FROM sales
GROUP BY payment
HAVING COUNT(*) > 2
ORDER BY payment;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 4

card was used only twice, so its group is dropped.

card تەنها دوو جار بەکار هاتووە، بۆیە گرووپەکەی لادەبرێت.

An aggregate cannot go in WHERE, because when WHERE runs there are no groups yet:

ناتوانێت لە WHEREـدا بێت، چونکە کاتێک WHERE کار دەکات هێشتا هیچ گرووپێک نییە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category FROM products WHERE COUNT(*) >= 2 GROUP BY category;   -- wrong

A condition on rows and a condition on groups can work together. Cash sales per seller, only for sellers with at least three of them:

لەسەر و لەسەر گرووپەکان دەتوانن پێکەوە کار بکەن. فرۆشتنی نەختینە بۆ هەر فرۆشیارێک، تەنها بۆ ئەو فرۆشیارانەی لانیکەم سێیان هەیە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT seller, COUNT(*) AS cash_sales
FROM sales
WHERE payment = 'cash'
GROUP BY seller
HAVING COUNT(*) >= 3
ORDER BY seller;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 3-5

WHERE keeps the 10 cash sales; grouping gives Lana 2 and Rezan 8; HAVING drops Lana's group.

WHERE ⁦10⁩ فرۆشتنە نەختینەکە دەهێڵێتەوە؛ گرووپکردن ⁦Lana 2⁩ و ⁦Rezan 8⁩ دەدات؛ HAVING گرووپی Lana لادەبات.

One more, from a database course's review notes: the average price of every category that has at least three products.

یەکێکی تر، لە تێبینییەکانی پێداچوونەوەی کۆرسێکی : تێکڕای قیمەتی هەر جۆرێک کە لانیکەم سێ کاڵای هەیە.

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category, AVG(price_iqd) AS average_price
FROM products
GROUP BY category
HAVING COUNT(*) >= 3
ORDER BY category;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 4

The headphones (2 products) are dropped. The averages show MySQL's four decimal places.

(⁦2⁩ کاڵا) لادەبرێن. تێکڕاکان چوار شوێنی دوای خاڵی MySQL پیشان دەدەن.

Quick checkپشکنینی خێراWhere does the condition only sales of more than one item belong in a grouped query? تەنها ئەو فرۆشتنانەی زیاتر لە یەک دانەن لە گرووپکراودا لە کوێ دادەنرێت؟

HAVING: keeping or dropping whole groupsHAVING: هێشتنەوە یان لابردنی گرووپی تەواو

Worked example, step by stepنموونەی شیکراوە، هەنگاو بە هەنگاو

For each category, find the cheapest product that costs at least 20,000 IQD — but only for categories that have at least two such products.

بۆ هەر جۆرێک، هەرزانترین ئەو کاڵایە بدۆزەرەوە کە لانیکەم ⁦20,000⁩ دینارە — بەڵام تەنها بۆ ئەو جۆرانەی لانیکەم دوو کاڵای وایان هەیە.

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category, COUNT(*) AS how_many, MIN(price_iqd) AS cheapest
FROM products
WHERE price_iqd >= 20000
GROUP BY category
HAVING COUNT(*) >= 2
ORDER BY category;
Animation in seven frames. 1: the twelve products. 2: WHERE price_iqd >= 20000 crosses out Fast Charger 33W (18,000) and Wired Earphones (7,500). 3: GROUP BY category colours the ten rows into four groups: charger 2, headphones 1, laptop 3, phone 4. 4: the size of each group is shown. 5: HAVING COUNT(*) >= 2 crosses out the headphones group. 6: in each remaining group the cheapest price is marked: 25,000, 600,000 and 165,000. 7: the answer table with three rows: charger 2 25000, laptop 3 600000, phone 4 165000.
Animation in seven frames. 1: the twelve products. 2: WHERE price_iqd >= 20000 crosses out Fast Charger 33W (18,000) and Wired Earphones (7,500). 3: GROUP BY category colours the ten rows into four groups: charger 2, headphones 1, laptop 3, phone 4. 4: the size of each group is shown. 5: HAVING COUNT(*) >= 2 crosses out the headphones group. 6: in each remaining group the cheapest price is marked: 25,000, 600,000 and 165,000. 7: the answer table with three rows: charger 2 25000, laptop 3 600000, phone 4 165000.
WHERE removes rows, GROUP BY makes groups, HAVING removes groups, then SELECT computes one row per group.WHERE لادەبات، ⁦GROUP BY⁩ گرووپ دروست دەکات، HAVING گرووپ لادەبات، پاشان SELECT بۆ هەر گرووپێک یەک دەژمێرێت.CêIT
  1. FROM — start with all 12 products.

    FROM — بە هەموو ⁦12⁩ کاڵاکە دەست پێبکە.

  2. WHERE price_iqd >= 20000 — the Fast Charger 33W (18,000) and the Wired Earphones (7,500) are removed; 10 rows are left.

    WHERE price_iqd >= 20000 — ⁦Fast Charger 33W (18,000)⁩ و ⁦Wired Earphones (7,500)⁩ لادەبرێن؛ ⁦10⁩ دەمێنێتەوە.

  3. GROUP BY category — charger 2 rows, headphones 1, laptop 3, phone 4.

    ⁦GROUP BY⁩ category — ⁦charger 2⁩ ، ⁦headphones 1⁩، ⁦laptop 3⁩، ⁦phone 4⁩.

  4. HAVING COUNT(*) >= 2 — the headphones group has only the Galaxy Buds FE, so it is dropped.

    HAVING COUNT(*) >= 2 — گرووپی headphones تەنها ⁦Galaxy Buds FE⁩ـی تێدایە، بۆیە لادەبرێت.

  5. SELECT — for each of the three groups left, write the category, COUNT(*) and MIN(price_iqd).

    SELECT — بۆ هەر یەک لەو سێ گرووپەی ماونەتەوە، جۆر، COUNT(*) و MIN(price_iqd) بنووسە.

  6. ORDER BY category — sort the three answer rows.

    ⁦ORDER BY⁩ category — سێ وەڵامەکە ڕیز بکە.

Quick checkپشکنینی خێراIf the condition were HAVING COUNT(*) >= 4, which categories would be left?ئەگەر HAVING COUNT(*) >= 4 بوایە، کام جۆر دەمایەوە؟

HAVING: keeping or dropping whole groupsHAVING: هێشتنەوە یان لابردنی گرووپی تەواو

Every row or some row: MAX and MIN in HAVINGهەموو تۆمارێک یان هەندێک تۆمار: MAX و MIN لە HAVING

Add one more wish: … and every product of the category costs at most 1,000,000 IQD. Standard SQL has an aggregate for every row is true, EVERY(price_iqd <= 1000000). MySQL and SQLite do not have it:

داواکارییەکی تر زیاد بکە: … و هەموو کاڵایەکی ئەو جۆرە لە ⁦1,000,000⁩ دینار زیاتر نییە. SQLـی ستاندارد بۆ هەموو ڕاستە هەیە، EVERY(price_iqd <= 1000000). MySQL و SQLite ئەوەیان نییە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category, MIN(price_iqd) FROM products
WHERE price_iqd >= 20000
GROUP BY category
HAVING COUNT(*) >= 2 AND EVERY(price_iqd <= 1000000);

Think about it differently: every price is at most 1,000,000 means the largest price is at most 1,000,000. So write MAX(…) <= …:

بە شێوەیەکی تر بیری لێ بکەرەوە: هەموو قیمەتێک لە ⁦1,000,000⁩ زیاتر نییە واتە گەورەترین قیمەت لە ⁦1,000,000⁩ زیاتر نییە. بۆیە بنووسە MAX(…) <= …:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category, COUNT(*) AS how_many, MIN(price_iqd) AS cheapest
FROM products
WHERE price_iqd >= 20000
GROUP BY category
HAVING COUNT(*) >= 2 AND MAX(price_iqd) <= 1000000
ORDER BY category;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 5

The phone group is dropped because the iPhone 15 costs 1,350,000.

گرووپی phone لادەبرێت چونکە ⁦iPhone 15 1,350,000⁩ دینارە.

And at least one product costs at most 1,000,000 (standard ANY or SOME) means the smallest price is at most 1,000,000: MIN(…) <= …. Then the phone group stays, thanks to its cheaper phones:

و لانیکەم یەک کاڵا لە ⁦1,000,000⁩ زیاتر نییە (ANY یان SOMEـی ستاندارد) واتە بچووکترین قیمەت لە ⁦1,000,000⁩ زیاتر نییە: MIN(…) <= …. ئەو کاتە گرووپی phone دەمێنێتەوە، بەهۆی مۆبایلە هەرزانترەکانیەوە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category, COUNT(*) AS how_many, MIN(price_iqd) AS cheapest
FROM products
WHERE price_iqd >= 20000
GROUP BY category
HAVING COUNT(*) >= 2 AND MIN(price_iqd) <= 1000000
ORDER BY category;
Every and some with MAX and MINهەموو و هەندێک بە MAX و MIN
You meanمەبەستت ئەمەیەStandard SQLSQLـی ستانداردWrite in MySQL and SQLiteلە MySQL و SQLite بنووسە
every row of the group has x <= vهەموو گرووپەکە x <= vـی هەیەEVERY(x <= v)MAX(x) <= v
some row of the group has x <= vهەندێک گرووپەکە x <= vـی هەیەANY / SOMEMIN(x) <= v
every row has x >= vهەموو x >= vـی هەیەEVERY(x >= v)MIN(x) >= v
some row has x >= vهەندێک x >= vـی هەیەANY / SOMEMAX(x) >= v
Quick checkپشکنینی خێراCategories in which every product has a stock of at least 5. Which HAVING condition is right?ئەو جۆرانەی هەموو کاڵایەکیان لانیکەم 5 دانەی لە کۆگادا هەیە. کام HAVING دروستە؟

HAVING: keeping or dropping whole groupsHAVING: هێشتنەوە یان لابردنی گرووپی تەواو

Filter before or after grouping?پێش یان دوای گرووپکردن بپاڵێوە؟

Is every product costs at most 1,000,000 the same as removing the expensive rows first with WHERE? Try it:

ئایا هەموو کاڵایەک لە ⁦1,000,000⁩ زیاتر نییە هەمان لابردنی کاڵا گرانەکانە بە WHERE لە سەرەتادا؟ تاقی بکەرەوە:

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category, COUNT(*) AS how_many, MIN(price_iqd) AS cheapest
FROM products
WHERE price_iqd BETWEEN 20000 AND 1000000
GROUP BY category
HAVING COUNT(*) >= 2
ORDER BY category;

No. WHERE throws away the iPhone row before grouping, so the phone group still has three cheaper phones and stays. With MAX(price_iqd) <= 1000000 in HAVING, the whole phone group is judged and dropped. On this data the WHERE version gives the same rows as the some row (MIN) version — but only by chance.

نەخێر. WHERE iPhone پێش گرووپکردن فڕێ دەدات، بۆیە گرووپی phone هێشتا سێ مۆبایلی هەرزانتری تێدایە و دەمێنێتەوە. لەگەڵ MAX(price_iqd) <= 1000000 لە HAVING، هەموو گرووپی phone هەڵدەسەنگێنرێت و لادەبرێت. لەسەر ئەم شێوەی WHERE هەمان شێوەی هەندێک (MIN) دەدات — بەڵام تەنها بە ڕێکەوت.

Three conditions, three meanings (all run in SQLite 3.51)سێ ، سێ واتا (هەموویان لە ⁦SQLite 3.51⁩ جێبەجێ کراون)
VersionشێوەPhone groupگرووپی phoneAnswerوەڵام
HAVING … AND MAX(price_iqd) <= 1000000dropped (the iPhone is in the group)لادەبرێت (iPhone لە گرووپەکەدایە)charger, laptop
HAVING … AND MIN(price_iqd) <= 1000000kept with 4 rowsبە 4 دەمێنێتەوەcharger, laptop, phone
WHERE price_iqd BETWEEN 20000 AND 1000000kept with 3 rows (the iPhone was removed first)بە 3 دەمێنێتەوە (iPhone لە سەرەتادا لابرا)charger, laptop, phone
Quick checkپشکنینی خێراWhich query lists the sellers who made more than 8 sales in total, counting every payment type?کام ئەو فرۆشیارانە پیشان دەدات کە بە گشتی زیاتر لە 8 فرۆشتنیان کردووە، هەموو جۆرێکی پارەدان دەژمێردرێت؟

The whole SELECT, and the order SQL reads itهەموو SELECT و ئەو ڕیزبەندییەی SQL پێی دەخوێنێتەوە

Here is the full shape of a SELECT. The parts must be written in this order; the parts in square brackets are optional.

ئەمە شێوەی تەواوی . بەشەکان دەبێت بەم ڕیزبەندییە بنووسرێن؛ ئەو بەشانەی لە ناو کەوانەی چوارگۆشەدان هەڵبژاردەن.

The SELECT templateقاڵبی SELECTTEXT
SELECT [DISTINCT] columns, expressions, aggregates
FROM table(s)
[WHERE row condition]
[GROUP BY columns]
[HAVING group condition]
[ORDER BY columns [ASC | DESC]]
[LIMIT n];

SQL does not read a query in the order it is written. Logically it works through these steps, each one handing a smaller table to the next:

SQL بەو ڕیزبەندییە ناخوێنێتەوە کە نووسراوە. بە شێوەی لۆجیکی بەم هەنگاوانەدا دەڕوات و هەر یەکێکیان بچووکتر دەداتە هەنگاوی دواتر:

  1. FROM (and joins) — collect the rows.
  2. WHERE — keep the rows where the condition is true.
  3. GROUP BY — form the groups.
  4. HAVING — keep the groups where the condition is true.
  5. SELECT — compute the columns, the aggregates and the aliases.
  6. DISTINCT — remove repeated answer rows.
  7. ORDER BY — sort.
  8. LIMIT — cut the list.
  1. FROM (و ) — کۆ دەکاتەوە.
  2. WHERE — ئەو دەهێڵێتەوە کە تێیاندا ڕاستە.
  3. GROUP BY — گرووپەکان دروست دەکات.
  4. HAVING — ئەو گرووپانە دەهێڵێتەوە کە تێیاندا ڕاستە.
  5. SELECT — ، و دەژمێرێت.
  6. DISTINCT — وەڵام لادەبات.
  7. ORDER BY — ڕیز دەکات.
  8. LIMIT — لیستەکە کورت دەکاتەوە.
A pipeline of eight boxes from left to right: FROM, WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, LIMIT. Under the boxes a small table shrinks step by step: 12 rows after FROM, 10 rows after WHERE, 4 groups after GROUP BY, 3 groups after HAVING, 3 answer rows after SELECT. Two notes: an alias is born at SELECT, so WHERE cannot use it but ORDER BY can; aggregates are worked out per group, so they can be used from HAVING onwards.زنجیرەیەک لە هەشت سندووق لە چەپەوە بۆ ڕاست: FROM، WHERE، GROUP BY، HAVING، SELECT، DISTINCT، ORDER BY، LIMIT. لە ژێر سندووقەکاندا خشتەیەکی بچووک هەنگاو بە هەنگاو بچووک دەبێتەوە: 12 تۆمار دوای FROM، 10 تۆمار دوای WHERE، 4 گرووپ دوای GROUP BY، 3 گرووپ دوای HAVING، 3 تۆماری وەڵام دوای SELECT. دوو تێبینی: نازناو لە SELECT لەدایک دەبێت، بۆیە WHERE ناتوانێت بەکاری بهێنێت بەڵام ORDER BY دەتوانێت؛ کردارەکانی کۆکردنەوە بۆ هەر گرووپێک دەژمێردرێن، بۆیە لە HAVINGـەوە بەدواوە بەکار دێن.
The logical order of a SELECT, shown on the worked example.ڕیزبەندیی لۆجیکیی SELECT، لەسەر نموونە شیکراوەکە پیشان دراوە.CêIT
Quick checkپشکنینی خێراIn SQL's logical order, which step comes straight after WHERE?لە ڕیزبەندیی لۆجیکیی SQLـدا، کام هەنگاو ڕاستەوخۆ دوای WHERE دێت؟

Secret To Optimizing SQL Queries - Understand The SQL Execution OrderByteByteGo · Englishئینگلیزی · 692K viewsبینین · 24K likesلایک

The order a database works through a SELECT: FROM and JOIN, WHERE, GROUP BY, HAVING, SELECT, ORDER BY and LIMIT, animated step by step.

ئەو ڕیزبەندییەی پێ جێبەجێ دەکات: FROM و JOIN، WHERE، GROUP BY، HAVING، SELECT، ORDER BY و LIMIT، بە هەنگاو بە هەنگاو.

Whole video: the logical order FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY, LIMIT, and why the optimiser may reorder the real work.

هەموو ڤیدیۆکە: ڕیزبەندییە لۆجیکییەکە (FROM، WHERE، GROUP BY، HAVING، SELECT، ORDER BY، LIMIT) و بۆچی لەوانەیە کارە ڕاستەقینەکە بە ڕیزبەندییەکی تر بکات.

The whole SELECT, and the order SQL reads itهەموو SELECT و ئەو ڕیزبەندییەی SQL پێی دەخوێنێتەوە

Which parts are needed, and what the order explainsکام بەشانە پێویستن و ڕیزبەندییەکە چی ڕوون دەکاتەوە

Only SELECT is always needed. The table shows when each of the other parts is used:

تەنها SELECT هەمیشە پێویستە. خشتەکە پیشان دەدات هەر یەک لە بەشەکانی تر کەی بەکار دێت:

The parts of SELECTبەشەکانی SELECT
PartبەشNeeded?پێویستە؟Its jobکارەکەی
SELECTalwaysهەمیشەwhich columns and values the answer showsوەڵامەکە کام و نرخ پیشان دەدات
FROMwhen the data comes from a table (SELECT 2 + 3; needs none)کاتێک لە دێت (SELECT 2 + 3; پێویستی پێی نییە)which tables (and joins)کام (و کام )
WHEREnoنەخێرfilters rows دەپاڵێوێت
GROUP BYfor one answer per groupبۆ یەک وەڵام بۆ هەر گرووپێکforms groupsگرووپ دروست دەکات
HAVINGno (normally with GROUP BY)نەخێر (ئاسایی لەگەڵ ⁦GROUP BY⁩)filters groupsگرووپەکان دەپاڵێوێت
ORDER BYnoنەخێرsorts the answerوەڵامەکە ڕیز دەکات
LIMITnoنەخێرkeeps only the first rowsتەنها یەکەم دەهێڵێتەوە

This order explains the rules of both SQL lessons: an alias cannot be used in WHERE (it is born at step 5) but can be used in ORDER BY (step 7); an aggregate cannot be used in WHERE (no groups yet) but can in HAVING, SELECT and ORDER BY. The database may use a faster plan inside, but the answer is always the same as if it had followed these steps. The most popular products, sorted by an aggregate alias:

ئەم ڕیزبەندییە یاساکانی هەردوو وانەی SQL ڕوون دەکاتەوە: لە WHEREـدا بەکار نایەت (لە هەنگاوی 5دا لەدایک دەبێت) بەڵام لە ORDER BYـدا بەکار دێت (هەنگاوی ⁦7⁩)؛ لە WHEREـدا بەکار نایەت (هێشتا هیچ گرووپێک نییە) بەڵام لە HAVING، SELECT و ORDER BYـدا بەکار دێت. لەوانەیە لە ناوەوە پلانێکی خێراتر بەکار بهێنێت، بەڵام وەڵامەکە هەمیشە وەک ئەوەیە کە ئەم هەنگاوانەی گرتبێتە بەر. بەناوبانگترین کاڵاکان، ڕیزکراو بەپێی :

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT p.name, SUM(s.quantity) AS sold
FROM sales AS s
INNER JOIN products AS p ON s.product_id = p.product_id
GROUP BY p.product_id, p.name
ORDER BY sold DESC, p.name
LIMIT 3;
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 4

Grouping by the primary key product_id keeps two products with the same name apart; p.name is added so that the name may be shown.

گرووپکردن بەپێی product_id دوو کاڵا بە هەمان ناو لە یەک جیا دەهێڵێتەوە؛ p.name زیاد کراوە بۆ ئەوەی ناوەکە پیشان بدرێت.

Quick checkپشکنینی خێراIn which step is the alias sold created, so that ORDER BY sold can use it? sold لە کام هەنگاودا دروست دەبێت، بۆ ئەوەی ORDER BY sold بتوانێت بەکاری بهێنێت؟

Where you will meet this againلە کوێ دووبارە ئەمە دەبینیتەوە

Grouping is everywhere that data is summarised:

گرووپکردن لە هەموو ئەو شوێنانەدایە کە کورت دەکرێتەوە:

  • Microsoft Access builds the same queries without typing: a totals query is GROUP BY with aggregates, and the Find Duplicates wizard writes GROUP BY … HAVING COUNT(*) > 1. In our shop, the cities with more than one customer:
  • ⁦Microsoft Access⁩ هەمان بەبێ نووسین دروست دەکات: پرسی کۆکردنەوە هەمان GROUP BYـە لەگەڵ و یاریدەدەری ⁦Find Duplicates⁩ دەنووسێت GROUP BY … HAVING COUNT(*) > 1. لە دوکانەکەماندا، ئەو شارانەی زیاتر لە یەک کڕیاریان هەیە:
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT city, COUNT(*) AS customers
FROM customers
GROUP BY city
HAVING COUNT(*) > 1;
  • PHP reports. A grouped query returns ordinary rows, so a PHP page reads them with the same loop as any SELECT (reading rows, SELECT and a while loop).
  • Database theory. Students who took every course is relational division; in SQL it is solved with GROUP BY and HAVING COUNT(…) (division, the algebra examples in SQL).
  • Python has the same idea for lists: sum(), min() and max() (sum, max and min).
  • Statistics. AVG is the arithmetic mean; a weighted mean such as an average mark weighted by course hours is SUM(mark * hours) / SUM(hours) (the weighted mean).
  • ڕاپۆرتەکانی PHP. گرووپکراو ئاسایی دەگەڕێنێتەوە، بۆیە پەڕەیەکی PHP بە هەمان خول وەک هەر SELECTـێک دەیانخوێنێتەوە (خوێندنەوەی تۆمارەکان، SELECT و خولێکی while).
  • تیۆری . ئەو خوێندکارانەی هەموو وانەیەکیان وەرگرتووە دابەشکردنی پەیوەندییە؛ لە SQLـدا بە GROUP BY و HAVING COUNT(…) چارەسەر دەکرێت (دابەشکردن، نموونەکانی جەبر لە SQL).
  • Python هەمان بیرۆکەی بۆ لیست هەیە: sum()، min() و max() (sum، max و min).
  • ئامار. AVG ژمێرەییە؛ وەک تێکڕای نمرە کە بەپێی کاتژمێری وانەکان قورس کراوە SUM(mark * hours) / SUM(hours)ـە (ناوەندی قورسکراو).

Exercisesڕاهێنانەکان

All tasks use the shop database. They follow the exercise ideas of the course's textbook chapter and lecture slides, moved to our shop.

هەموو ئەرکەکان دوکانەکە بەکار دەهێنن. بیرۆکەی ڕاهێنانەکانی بەشی کتێبەکە و سلایدەکانی وانەی کۆرسەکە دەگرنەبەر کە گوازراونەتەوە بۆ دوکانەکەمان.

Exerciseڕاهێنان

1. Name a function for each job: (a) the weekday name of 21 March 1991, (b) a number of characters from a given position of a text, (c) the name of the month you were born in, (d) your name in capital letters.

1. بۆ هەر کارێک ناو بهێنە: (أ) ناوی ڕۆژی هەفتەی ⁦21⁩ی ئازاری ⁦1991⁩، (ب) چەند لە شوێنێکی دیاریکراوی دەقێکەوە، (ج) ناوی ئەو مانگەی تێیدا لەدایک بوویت، (د) ناوەکەت بە پیتی گەورە.

Show answerوەڵامەکە پیشان بدە
  • (a) DAYNAME('1991-03-21') (b) SUBSTRING(), also written SUBSTR() or MID() (c) MONTHNAME() (d) UPPER() or UCASE().
  • (أ) DAYNAME('1991-03-21') (ب) SUBSTRING()، کە بە SUBSTR() یان MID()ـیش دەنووسرێت (ج) MONTHNAME() (د) UPPER() یان UCASE().
Exerciseڕاهێنان

2. Predict what MySQL prints, then check in phpMyAdmin: SELECT POW(2, 3), ROUND(342.9234, -1), LENGTH('Information Technology'); — SELECT YEAR('1991-03-21'), MONTH('1991-03-21'), DAY('1991-03-21'), MONTHNAME('1991-03-21'), DAYNAME('1991-03-21'); — SELECT LEFT('Kurdistan', 4), RIGHT('Sulaimani', 4), MID('Halabja', 3, 3), SUBSTR('Erbil', 3);

2. پێشبینی بکە MySQL چی چاپ دەکات، پاشان لە phpMyAdmin بیپشکنە: SELECT POW(2, 3), ROUND(342.9234, -1), LENGTH('Information Technology'); — SELECT YEAR('1991-03-21'), MONTH('1991-03-21'), DAY('1991-03-21'), MONTHNAME('1991-03-21'), DAYNAME('1991-03-21'); — SELECT LEFT('Kurdistan', 4), RIGHT('Sulaimani', 4), MID('Halabja', 3, 3), SUBSTR('Erbil', 3);

Show answerوەڵامەکە پیشان بدە
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT POW(2, 3), ROUND(342.9234, -1), LENGTH('Information Technology');
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT YEAR('1991-03-21'), MONTH('1991-03-21'), DAY('1991-03-21'),
       MONTHNAME('1991-03-21'), DAYNAME('1991-03-21');
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT LEFT('Kurdistan', 4), RIGHT('Sulaimani', 4), MID('Halabja', 3, 3), SUBSTR('Erbil', 3);

Information Technology has 22 characters, all English, so LENGTH and CHAR_LENGTH agree. 21 March 1991 — Newroz — was a Thursday.

⁦Information Technology⁩ ⁦22⁩ هەیە، هەمووی ئینگلیزی، بۆیە LENGTH و CHAR_LENGTH وەک یەکن. ⁦21⁩ی ئازاری ⁦1991⁩ — نەورۆز — پێنجشەممە بوو.

Exerciseڕاهێنان

3. (a) How many products does each brand have? (b) Without running them, predict the answers of: SELECT DISTINCT brand FROM products WHERE category = 'laptop';, SELECT COUNT(DISTINCT category) FROM products; and SELECT category, MAX(price_iqd), MIN(price_iqd) FROM products GROUP BY category ORDER BY category;

3. (أ) هەر براندێک چەند کاڵای هەیە؟ (ب) بەبێ جێبەجێکردن، پێشبینیی وەڵامی ئەمانە بکە: SELECT DISTINCT brand FROM products WHERE category = 'laptop';، SELECT COUNT(DISTINCT category) FROM products; و SELECT category, MAX(price_iqd), MIN(price_iqd) FROM products GROUP BY category ORDER BY category;

Show answerوەڵامەکە پیشان بدە
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT brand, COUNT(*) AS products
FROM products
GROUP BY brand
ORDER BY products DESC, brand;
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT DISTINCT brand FROM products WHERE category = 'laptop';
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT COUNT(DISTINCT category) FROM products;
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT category, MAX(price_iqd), MIN(price_iqd)
FROM products
GROUP BY category
ORDER BY category;
Exerciseڕاهێنان

4. What is the average price of the Xiaomi products, and how many different brands of phone does the shop sell?

4. تێکڕای قیمەتی کاڵاکانی Xiaomi چەندە و دوکانەکە چەند براندی جیاوازی مۆبایل دەفرۆشێت؟

Show answerوەڵامەکە پیشان بدە
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT AVG(price_iqd) FROM products WHERE brand = 'Xiaomi';
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT COUNT(DISTINCT brand) FROM products WHERE category = 'phone';
Exerciseڕاهێنان

5. Discounts (practise on a copy). Make a fresh copy of products and give it a column discount_iqd. Phones get no discount, laptops 10 % and everything else 5 %, rounded to whole dinars. Then find: (a) the most expensive laptop, (b) the average and the total discount of the Lenovo products, (c) how many products have no discount.

5. داشکاندن (لەسەر کۆپییەک ڕاهێنان بکە). کۆپییەکی نوێی products دروست بکە و discount_iqdـی پێ بدە. مۆبایل هیچ داشکاندنێکی نییە، ⁦10 %⁩ و هەموو شتێکی تر ⁦5 %⁩، خڕکراوە بۆ دیناری تەواو. پاشان بیدۆزەرەوە: (أ) گرانترین ، (ب) تێکڕا و کۆی داشکاندنی کاڵاکانی Lenovo، (ج) چەند کاڵا هیچ داشکاندنێکیان نییە.

Show answerوەڵامەکە پیشان بدە
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
DROP TABLE IF EXISTS products_copy;
CREATE TABLE products_copy AS SELECT * FROM products;
ALTER TABLE products_copy ADD discount_iqd INT;

UPDATE products_copy SET discount_iqd = 0 WHERE category = 'phone';
UPDATE products_copy SET discount_iqd = ROUND(price_iqd * 0.10) WHERE category = 'laptop';
UPDATE products_copy SET discount_iqd = ROUND(price_iqd * 0.05) WHERE category NOT IN ('phone', 'laptop');
Explain the codeڕوونکردنەوەی کۆدەکە
Lineدێڕی 3

ALTER TABLE … ADD adds a column to an existing table; every row gets NULL until the updates fill it in.

ALTER TABLE … ADD بۆ هەبوو زیاد دەکات؛ هەموو NULL وەردەگرێت تا UPDATEـەکان پڕی دەکەنەوە.

SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
-- (a)
SELECT name, price_iqd FROM products_copy
WHERE category = 'laptop'
  AND price_iqd = (SELECT MAX(price_iqd) FROM products_copy WHERE category = 'laptop');
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
-- (b)
SELECT AVG(discount_iqd), SUM(discount_iqd) FROM products_copy WHERE brand = 'Lenovo';
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
-- (c)
SELECT COUNT(*) FROM products_copy WHERE discount_iqd = 0;

The ThinkPad (940,000 IQD) is the most expensive laptop; the Lenovo discounts are 61,000 and 94,000. Note that the condition of (a) must be repeated inside the subquery — otherwise it would look for a laptop costing 1,350,000, the price of the iPhone.

⁦ThinkPad (940,000⁩ دینار) گرانترین ؛ داشکاندنەکانی ⁦Lenovo 61,000⁩ و ⁦94,000⁩ـن. سەرنج بدە کە (أ) دەبێت لە ناو دووبارە بکرێتەوە — دەنا بەدوای دەگەڕێت کە ⁦1,350,000⁩ دینار بێت، قیمەتی iPhone.

Exerciseڕاهێنان

6. The shop raises all Xiaomi prices by 12 %, rounded to the nearest thousand dinars. Write the UPDATE (on the copy) and say what the new prices are.

6. دوکانەکە هەموو قیمەتەکانی Xiaomi بە ⁦12 %⁩ بەرز دەکاتەوە، خڕکراوە بۆ نزیکترین هەزار دینار. UPDATEـەکە بنووسە (لەسەر کۆپییەکە) و بڵێ قیمەتە نوێیەکان چەندن.

Show answerوەڵامەکە پیشان بدە
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
UPDATE products_copy SET price_iqd = ROUND(price_iqd * 1.12, -3) WHERE brand = 'Xiaomi';
SELECT name, price_iqd FROM products_copy WHERE brand = 'Xiaomi';
Exerciseڕاهێنان

7. How many purchases did each customer make? Which customers made more than three?

7. هەر کڕیارێک چەند جار کڕینی کردووە؟ کام کڕیار زیاتر لە سێ جار؟

Show answerوەڵامەکە پیشان بدە
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT customer_id, COUNT(*) AS purchases
FROM sales
GROUP BY customer_id
ORDER BY customer_id;
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT customer_id, COUNT(*) AS purchases
FROM sales
GROUP BY customer_id
HAVING COUNT(*) > 3
ORDER BY customer_id;

Customers 1, 2 and 3 are Aram, Shilan and Karwan. To print their names, join customers and group by c.customer_id, c.name.

کڕیارەکانی 1، 2 و ⁦3 Aram⁩، Shilan و Karwanـن. بۆ چاپکردنی ناوەکانیان customers ببەستەوە و بەپێی c.customer_id, c.name گرووپ بکە.

Exerciseڕاهێنان

8. Which products have never been sold?

8. کام کاڵا هەرگیز نەفرۆشراوە؟

Show answerوەڵامەکە پیشان بدە
SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات
SELECT name FROM products
WHERE product_id NOT IN (SELECT product_id FROM sales);

This is safe because sales.product_id is NOT NULL. If the subquery could return a NULL, NOT IN would return no rows at all (the NOT IN and NULL surprise); a LEFT JOIN … WHERE s.sale_id IS NULL (outer joins) avoids the problem.

ئەمە سەلامەتە چونکە sales.product_id NOT NULLـە. ئەگەر بیتوانیایە NULL بگەڕێنێتەوە، NOT IN هیچ نەدەگەڕاندەوە (سەرسوڕمانی ⁦NOT IN⁩ و NULL)؛ LEFT JOIN … WHERE s.sale_id IS NULL (لێکبەستنە دەرەکییەکان) لەم کێشەیە دوور دەکەوێتەوە.

Exerciseڕاهێنان

9. Explain in two sentences what ORDER BY and GROUP BY are for, and give two differences between single-row and aggregate functions.

9. بە دوو ڕستە ڕوون بکەرەوە ORDER BY و GROUP BY بۆ چین و دوو جیاوازی لە نێوان و بهێنەرەوە.

Show answerوەڵامەکە پیشان بدە
  • ORDER BY only sorts the rows of the answer; the number of rows stays the same. GROUP BY puts rows with equal values into groups so that aggregates give one row per group — the answer usually has fewer rows.
  • A single-row function gives one result for every row and can be used in WHERE; an aggregate gives one result for a group of rows and cannot be used in WHERE (use HAVING).
  • ORDER BY تەنها وەڵامەکە ڕیز دەکات؛ ژمارەی وەک خۆی دەمێنێتەوە. GROUP BY ئەو نرخی یەکسانیان هەیە دەخاتە گرووپەوە بۆ ئەوەی بۆ هەر گرووپێک یەک بدەن — وەڵامەکە زۆرجار کەمتری هەیە.
  • بۆ هەموو یەک ئەنجام دەدات و لە WHEREـدا بەکار دێت؛ بۆ گرووپێک یەک ئەنجام دەدات و لە WHEREـدا بەکار نایەت (HAVING بەکار بهێنە).

Common mistakesهەڵە باوەکان

Mistakes with functions and groupingهەڵەکان لەگەڵ و گرووپکردن
MistakeهەڵەWhat happensچی ڕوودەداتFixچارەسەر
WHERE COUNT(*) > 2ERROR 1111: Invalid use of group functionهەڵەی ⁦1111: Invalid use of group function⁩HAVING COUNT(*) > 2
SELECT category, name, COUNT(*) … GROUP BY categoryMySQL 8.4: ERROR 1055; MariaDB and SQLite: a random name⁦MySQL 8.4: ERROR 1055⁩؛ MariaDB و SQLite: ناوێکی هەڕەمەکیaggregate the column or add it to GROUP BY بخەرە ناو یان بیخەرە ⁦GROUP BY⁩
SELECT name, MAX(price_iqd) FROM productsMySQL 8.4: ERROR 1140; elsewhere a name that may be wrong⁦MySQL 8.4: ERROR 1140⁩؛ لە شوێنی تر ناوێک کە لەوانەیە هەڵە بێتa subquery: WHERE price_iqd = (SELECT MAX(price_iqd) …): WHERE price_iqd = (SELECT MAX(price_iqd) …)
COUNT(email)skips NULL e-mails: 5, not 6 customers NULL پشتگوێ دەخات: 5، نەک 6 کڕیارCOUNT(*) to count rowsCOUNT(*) بۆ ژماردنی
AVG(stock)divides by the known values only (NULL is not 0)تەنها دابەشی نرخە زانراوەکان دەکات (⁦NULL 0⁩ نییە)AVG(COALESCE(stock, 0)) only if a missing value really means 0AVG(COALESCE(stock, 0)) تەنها ئەگەر نرخی ون بە ڕاستی واتای 0 بێت
SUM(quantity) when no row matchesSUM(quantity) کاتێک هیچ نەگونجێتNULL, not 0NULL، نەک 0COALESCE(SUM(quantity), 0)
LENGTH(name) on Kurdish textLENGTH(name) لەسەر دەقی کوردیcounts bytes: 10 for شیلان دەژمێرێت: ⁦10⁩ بۆ شیلانCHAR_LENGTH(name)
EVERY(price_iqd <= 1000000)no such function in MySQL or SQLite وا لە MySQL یان SQLite نییەMAX(price_iqd) <= 1000000
ROUND(x, -3) in SQLiteROUND(x, -3) لە SQLitethe −3 is ignored⁦−3⁩ پشتگوێ دەخرێتround(x / 1000.0) * 1000
CONCAT(name, email)NULL if the e-mail is NULL (MySQL)NULL ئەگەر NULL بێت ⁦(MySQL)⁩CONCAT_WS(' ', name, email)
GROUP BY seller without ORDER BYGROUP BY seller بەبێ ORDER BYMariaDB sorts the groups, MySQL 8 does notMariaDB گرووپەکان ڕیز دەکات، ⁦MySQL 8⁩ نا… GROUP BY seller ORDER BY seller

Summary and reviewپوختە و پێداچوونەوە

  • A single-row function gives one result per row (ROUND, UPPER, YEAR) and can be used in SELECT, WHERE and ORDER BY. An aggregate function gives one result per group (COUNT, SUM, AVG, MIN, MAX) and is used in SELECT, HAVING and ORDER BY.
  • ROUND(n, -3) rounds to thousands in MySQL (SQLite ignores negative places); MOD and FLOOR split amounts; POWER raises to a power.
  • Positions in text start at 1. LENGTH counts bytes and CHAR_LENGTH characters — a Kurdish letter is 2 bytes in UTF-8. INSTR + LEFT/SUBSTRING split text; CONCAT gives NULL if any part is NULL.
  • Date parts: YEAR, MONTH, DAY, MONTHNAME, DAYNAME, DAYOFWEEK; they work in WHERE, for example to find Friday sales.
  • COUNT(*) counts rows, COUNT(col) non-NULL values, COUNT(DISTINCT col) different values. Aggregates skip NULL; with no rows COUNT gives 0 and the others NULL. MIN and MAX work on text and dates.
  • With GROUP BY every plain column of SELECT must be grouped (MySQL 8.4 enforces it with ONLY_FULL_GROUP_BY). WHERE filters rows before grouping, HAVING filters groups after it; write every as MAX(…) <= and some as MIN(…) <=.
  • Logical order: FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT.
  • بۆ هەر یەک ئەنجام دەدات (ROUND، UPPER، YEAR) و لە SELECT، WHERE و ⁦ORDER BY⁩ بەکار دێت. بۆ هەر گرووپێک یەک ئەنجام دەدات (COUNT، SUM، AVG، MIN، MAX) و لە SELECT، HAVING و ⁦ORDER BY⁩ بەکار دێت.
  • ROUND(n, -3) لە MySQL بۆ هەزاران خڕ دەکاتەوە (SQLite شوێنی سالب پشتگوێ دەخات)؛ MOD و FLOOR بڕەکان دابەش دەکەن؛ POWER ئەنجام دەدات.
  • شوێن لە دەقدا لە 1ـەوە دەست پێدەکات. LENGTH دەژمێرێت و CHAR_LENGTH — پیتێکی کوردی لە ⁦UTF-8⁩دا 2 . INSTR + LEFT/SUBSTRING دەق لەت دەکەن؛ CONCAT NULL دەدات ئەگەر هەر بەشێک NULL بێت.
  • بەشەکانی بەروار: YEAR، MONTH، DAY، MONTHNAME، DAYNAME، DAYOFWEEK؛ لە WHEREـدا کار دەکەن، بۆ نموونە بۆ دۆزینەوەی فرۆشتنەکانی هەینی.
  • COUNT(*) دەژمێرێت، COUNT(col) ئەو نرخانەی NULL نین، COUNT(DISTINCT col) نرخە جیاوازەکان. NULL پشتگوێ دەخەن؛ بەبێ هیچ ⁦COUNT 0⁩ دەدات و ئەوانی تر ⁦NULL. MIN⁩ و MAX لەسەر دەق و بەروار کار دەکەن.
  • لەگەڵ ⁦GROUP BY⁩ هەموو ئاسایی SELECT دەبێت گرووپ بکرێت (⁦MySQL 8.4⁩ بە ⁦ONLY_FULL_GROUP_BY⁩ ناچاری دەکات). WHERE پێش گرووپکردن دەپاڵێوێت، HAVING دوای ئەوە گرووپەکان؛ هەموو وەک MAX(…) <= و هەندێک وەک MIN(…) <= بنووسە.
  • ڕیزبەندیی لۆجیکی: FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT.
Review questionsپرسیارەکانی پێداچوونەوە
What is the difference between WHERE and HAVING?جیاوازیی نێوان WHERE و HAVING چییە؟

WHERE keeps or removes single rows before grouping and cannot use aggregates. HAVING keeps or removes whole groups after GROUP BY and can use aggregates.

WHERE پێش گرووپکردن دەهێڵێتەوە یان لادەبات و ناتوانێت بەکار بهێنێت. HAVING دوای ⁦GROUP BY⁩ گرووپی تەواو دەهێڵێتەوە یان لادەبات و دەتوانێت بەکار بهێنێت.

Why does SELECT name, MAX(price_iqd) FROM products; fail in MySQL 8.4, and what do you write instead?بۆچی SELECT name, MAX(price_iqd) FROM products; لە ⁦MySQL 8.4⁩ هەڵە دەدات و لە جیاتی ئەوە چی دەنووسیت؟

MAX gives one value, but name has twelve; ONLY_FULL_GROUP_BY refuses to pick one (ERROR 1140). Write SELECT name, price_iqd FROM products WHERE price_iqd = (SELECT MAX(price_iqd) FROM products);.

MAX یەک نرخ دەدات، بەڵام name دوازدە نرخی هەیە؛ ⁦ONLY_FULL_GROUP_BY⁩ ڕەت دەکاتەوە یەکێکیان هەڵبژێرێت ⁦(ERROR 1140)⁩. بنووسە SELECT name, price_iqd FROM products WHERE price_iqd = (SELECT MAX(price_iqd) FROM products);.

The laptops' stocks are 4, NULL and 5. What are COUNT(*), COUNT(stock) and AVG(stock)?کۆگای لاپتۆپەکان 4، NULL و 5ـە. ⁦COUNT(*)⁩، ⁦COUNT(stock)⁩ و ⁦AVG(stock)⁩ چەندن؟

3, 2 and 4.5 (4.5000 in MySQL): the NULL is not counted and not averaged.

3، 2 و ⁦4.5 (4.5000⁩ لە ⁦MySQL): NULL⁩ نە دەژمێردرێت و نە تێکڕای لێ دەردەهێنرێت.

Why can ORDER BY use an aggregate alias such as sold, while WHERE cannot use any alias?بۆچی ⁦ORDER BY⁩ دەتوانێت نازناوی کردارێکی کۆکردنەوە وەک sold بەکار بهێنێت، لە کاتێکدا WHERE ناتوانێت هیچ نازناوێک بەکار بهێنێت؟

Aliases are made at the SELECT step, which comes after WHERE and before ORDER BY.

لە هەنگاوی SELECTـدا دروست دەکرێن، کە دوای WHERE و پێش ⁦ORDER BY⁩ دێت.

Videoڤیدیۆ

Watch a videoسەیری ڤیدیۆیەک بکە

A video that viewers liked a lot and praised in their comments, chosen for this lesson.ڤیدیۆیەک کە بینەران زۆریان پێ خۆش بووە و لە کۆمێنتەکانیاندا ستایشیان کردووە، بۆ ئەم وانەیە هەڵبژێردراوە.

MySQL: GROUP BYBro Code · Englishئینگلیزی · 134K viewsبینین · 3.8K likesلایک

GROUP BY in MySQL: one answer per group with SUM, MAX, MIN, AVG and COUNT, then HAVING to keep only some groups.

لە : یەک وەڵام بۆ هەر گرووپێک بە SUM، MAX، MIN، AVG و COUNT، پاشان بۆ هێشتنەوەی تەنها هەندێک گرووپ.

Whole video, MySQL: GROUP BY with aggregates 0:00, HAVING 3:19; the heart of this lesson in five minutes.

هەموو ڤیدیۆکە، بە : لەگەڵ لە ⁦0:00⁩ و لە ⁦3:19⁩؛ کرۆکی ئەم وانەیە لە پێنج خولەکدا.

Lesson complete!وانەکە تەواو بوو!

Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.

Key termsزاراوە سەرەکییەکان

Next lessonوانەی داهاتوو

Connecting PHP to MySQLپەیوەندیکردنی PHP بە MySQL

References and further readingسەرچاوەکان و خوێندنەوەی زیاتر

This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.