איך AI יכול לשפר את ה־SQL שלך
שפת ה-SQL היא אחד הכלים החשובים בארסנל של אנשי הדאטה, והיא מלווה אותנו כמעט בכל משימה – משליפות פשוטות ועד דוחות מורכבים.
מי שעובד עם השפה יודע שלא תמיד השאילתות שאנחנו כותבים הם הכי קריאים, הכי קצרים או הכי יעילים. לא פעם אנחנו מסתפקים בפתרון שעובד גם אם הוא מסורבל, קשה לתחזוקה או רץ לאט.
If it works don't touch it, נכון?
אז למשבצת הזו יכול להכנס ה־AI. לא בתור תחליף, אלא כמישהו / משהו שעוזר לשכתב שאילתות, מציע סגנונות חדשים של כתיבה, חושף אותנו ל־best practices, מסביר מה בדיוק השאילתה עושה, מפרק קוד ארוך למבנים יותר מסודרים, ואפילו כפרטנר שמאתגר אותנו לחשוב אחרת וללמוד את השפה טוב יותר.
בפוסט הזה אגע בנקודות האלו, וגם אדבר על הצד השני של המטבע – המגבלות שכדאי לשים לב אליהן.
תוכן עניינים
שכתוב שאילתות קיימות
ב־SQL אחת הבעיות היא שלעיתים שאילתות נוטות "להתנפח". אנחנו מתחילים עם שאילתה קטנה, מוסיפים עוד join, מכניסים תנאי, פתאום עוד subquery – ובסוף מתקבלת מפלצת שקשה לנו, הכותבים שלה, להבין. ועוד לא התחלנו לדבר על אלו שיצטרכו לקרוא אותה אחרינו.
זה למשל יוזקייס נהדר ל־AI: אפשר פשוט להדביק לו את השאילתה ולבקש לשכתב אותה בצורה קריאה וברורה יותר. ברוב המקרים הוא יחלק את הקוד לחלקים לוגיים, יסדר הזחות, ישתמש ב־CTEs או יציע חלופה קריאה יותר, בלי לשנות את הלוגיקה העסקית.
קחו למשל את השאילתה הבאה, כמה פשוט לכם להבין מה היא עושה?
<xmp>SELECT c.CustomerID, c.CompanyName,
(SELECT COUNT(*)
FROM Orders o
WHERE o.CustomerID = c.CustomerID
AND o.OrderDate >= '2024-01-01') AS RecentOrders
FROM Customers c
WHERE c.CustomerID IN (
SELECT DISTINCT CustomerID
FROM Orders
WHERE Freight > 100
);
</xmp>
ומה אם אותה השאילתה תהיה כתובה ככה?
<xmp>-- This query retrieves customers who placed high-freight orders
-- (Freight > 100), along with the number of orders they made in 2024.
WITH Orders2024 AS (
-- CTE #1: For each customer, count how many orders were placed in 2024
SELECT
CustomerID,
COUNT(*) AS RecentOrders
FROM Orders
WHERE OrderDate >= '2024-01-01'
GROUP BY CustomerID
),
HighFreight AS (
-- CTE #2: Get all distinct customers who had at least one order
-- with Freight cost greater than 100
SELECT DISTINCT
CustomerID
FROM Orders
WHERE Freight > 100
)
SELECT
c.CustomerID,
c.CompanyName,
o.RecentOrders
FROM Customers c
-- Join with Orders2024 to add order counts for 2024 (if available)
LEFT JOIN Orders2024 o
ON c.CustomerID = o.CustomerID
-- Inner join with HighFreight to ensure only customers with high-freight orders are included
INNER JOIN HighFreight h
ON c.CustomerID = h.CustomerID;
</xmp>
כלי לשיפור סטנדרטים של כתיבה ו־Best Practices
מנסיוני, שאילתות לא תמיד נראות כ״כ קריאות וברורות כמו דוגמאות בית-ספר היפות שמופיעות פה. לכולנו להתקל בשאילתות בהן אין הקפדה על גודל אות, כינויים הגיוניים (לעמודות / טבלאות), תיעוד ברור, הזחות ועוד.
במקרים כאלו אפשר להשתמש ב-AI ככלי שמוודא שהשאילתות שלנו עומדות בסטנדרטים של כתיבה ו‑Best Practices נכונים*, ומתקן שאילתות שהן לא.
לא שזו מטלה קשה מדי לבן-אנוש, כן?, אבל עדין – זה המון עבודה שחורה והתעסקות.
* לכל ארגון יש את הסטנדרט המקובל שלו, ואין דבר כזה כתיבה ״נכונה״ אחת. ועדיין, איזה כיף לקרוא את השאילתה הזו, נכון?
<xmp>select OrderID, OrderDate, CustomerID, CompanyName
from orders o join customers c on o.customerid=c.customerid
where orderdate > '2024-01-01' and country = 'Germany';
</xmp>
אבל תסכימו איתי שיהיה עוד יותר כיף לקרוא אותה ככה:
<xmp>-- Retrieves recent orders for customers from Germany
SELECT
ord.OrderID,
ord.OrderDate,
ord.CustomerID,
cust.CompanyName
FROM Orders AS ord
INNER JOIN Customers AS cust
ON ord.CustomerID = cust.CustomerID
WHERE ord.OrderDate > '2024-01-01'
AND cust.Country = 'Germany';
</xmp>
אמצעי ללימוד סגנונות חדשים בכתיבת SQL
אחד היתרונות המעניינים של שימוש ב־AI הוא שהוא מאפשר לנו לגלות סגנונות כתיבה חדשים וגישות שלא היינו חושבים עליהן בעצמנו. לדוגמה, ב־Google BigQuery אפשר לבצע פילטור לפי פונקציות חלון בצורה הרבה יותר קצרה וקריאה באמצעות QUALIFY – משהו שלא תמיד מובן למי שרגיל לכתוב הרבה subqueries או CTEs ומגיע מסביבות אחרות.
קחו לדוגמא את השאילתה הבאה:
<xmp>WITH RankedOrders AS (
SELECT CustomerID, OrderID,
ROW_NUMBER() OVER(PARTITION BY CustomerID
ORDER BY OrderDate DESC) AS rn
FROM Orders
)
SELECT *
FROM RankedOrders
WHERE rn = 1;</xmp>
בסביבת BQ אפשר היה לקצר אותה באופן משמעותי, ולשכתב באופן הבא:
<xmp>SELECT CustomerID, OrderID
FROM Orders
QUALIFY ROW_NUMBER() OVER(PARTITION BY CustomerID ORDER BY OrderDate DESC) = 1;
</xmp>
כלי ללמידה או בדיקת הבנה
מכירים את זה שנותנים לכם לתחזק שאילתה באורך של 200 שורות, בבלאגן היסטרי, ואתם מתלבטים מה יהיה יותר פשוט – להבין אותה, או לנסח מכתב התפטרות?
זה עוד יוזקייס מצויין עבור ה-AI, לבקש ממנו להסביר מה השאילתה עושה, צעד אחר צעד.ההסבר מפרק את השאילתה לחלקים ברורים: מה מחזיר כל CTE, איך ה־JOINים מתחברים, ומה מתקבל בסוף.
אפשר ומומלץ לקחת את זה צעד קדימה באמצעות ה-Study Mode. ואז במקום לקבל תשובה, אנחנו מקבלים הסבר. זה כבר לוקח את ה-AI והופך אותו מכלי שפותר בעיות, לכלי למידה אינטראקטיבי, שמאפשר לנו להבין לעומק לא רק מה השאילתה עושה, אלא גם איך אנחנו עצמנו מנתחים ומבינים את ה-SQL הבא שיתנו לנו.
* מצב ה Study Mode לא ייחודי רק לצ׳ט ג׳יפיטי, אלא גם אפשרי ב Gemeni ו- Claude.
כתיבת שאילתות מ-0
AI יכול לשמש ככלי שמלווה אותנו לאורך כל תהליך כתיבת השאילתה, ממש מהשלב הראשון של חשיבה על מה אנחנו רוצים להוציא מהנתונים ועד הפלט הסופי.
אבל, כדי שה‑AI יוכל להיות פרטנר אפקטיבי, חייבים לעמוד בשני קריטריונים
- קודם כל – אנחנו צריכים להכיר SQL ברמה טובה, וכל המרבה הרי זה משובח. אם אין הבנה מה ההבדל בין WHERE ל-HAVING, מהן העקרונות של JOIN, וכן הלאה – הסיכוי שהצ׳ט יזרוק לנו הזיות ואנחנו נזרום איתו גבוהות. עוד נדבר על כך בפסקת המגבלות של השימוש בכלי.
- הפרומפט חייב להיות מדויק ואינפורמטיבי – חייבים לכלול את שמות הטבלאות והעמודות, ואפילו את מבנה הטבלאות (DDL) או תרשים ERD אם יש. בנוסף, חשוב לציין במפורש ובמפורט את המטרה של השאילתה – מה בדיוק אנחנו רוצים לחשב או להציג.
כתוב לי שאילתת SQL למערכת המבוססת על PostgreSQL.
מטרת השאילתה: מצא את שלושת הלקוחות (customer_id) בעלי הסכום הכולל הגבוה ביותר של הזמנות בחודש ספטמבר 2024. הצג את שם הלקוח (customer_name) ואת סך ההזמנות (total_orders_amount).
מבנה הטבלאות:
customers(טבלת לקוחות):customer_id(INT, Primary Key)customer_name(VARCHAR)registration_date(DATE)
orders(טבלת הזמנות):order_id(INT, Primary Key)customer_id(INT, Foreign Key ל-customers)order_date(DATE)amount(NUMERIC)
וודא שהקוד קריא ומסודר.
למהדרין – אפשר לקחת את זה שלב אחד קדימה, ובמקום לבקש ממנו את התשובה, לבקש ממנו ללמד אותנו איך להגיע לתשובה בעצמנו באמצעות ה study mode
אני רוצה לכתוב שאילתת SQL למערכת PostgreSQL שמוצאת את שלושת הלקוחות בעלי סך ההזמנות הגבוה ביותר בחודש ספטמבר 2024.
מבנה הטבלאות: customers ו-orders (כפי שתיארתי קודם).
המטרה שלי היא ללמוד: אני רוצה שתנחה אותי לפתרון שלב אחר שלב, תוך שימוש ב-CTE לשיפור הקריאות.
אל תכתוב את הקוד הסופי. במקום זאת, הצג את הבעיה בחלוקה ל-3 שלבים לוגיים. עבור כל שלב, תן לי רמז ואת הפקודות הרלוונטיות שאצטרך (לדוגמה: GROUP BY, SUM(), JOIN). רק לאחר שאני מאשר שסיימתי שלב, המשך לשלב הבא.
איתור וניתוח שגיאות SQL
זה יוז-קייס נהדר, שלי אישית חסך לי המון זמן. במקום לבלות דקות או שעות בניסיון לפענח הודעת שגיאה גנרית, אפשר פשוט להדביק את הקוד ואת הודעת השגיאה ל-AI.
לרוב, ה-AI יודע לזהות במהירות שגיאות סינטקס בסיסיות (כגון פסיק חסר, טעות כתיב בשם עמודה או טבלה, או סוגריים לא סגורים) וגם שגיאות לוגיות מורכבות. הוא יכול להצביע על JOINים חסרים או שגויים, או שימוש לא נכון בהקבצות.
לא רק שהוא מתקן את השגיאה, ומראה מה צריך לעשות. הוא גם מסביר למה השגיאה התרחשה, מה שהופך את כל התהליך איתו לכלי למידה מעולה.
כמה זמן יקח לכם לאתר את כל השגיאות פה? כמה זמן יקח ל-AI? 🙂
<xmp>WITH RecentCustomers AS (
SELECT
customer_id
customer_name
FROM
customers
WHERE
registration_date < '2024-01-01'
),
SupplierOrderValues AS (
SELECT
s.supplier_name,
o.order_id,
o.amount
FROM
orders o
JOIN
products p ON o.product_id = p.product_id
JOIN
suppliers s ON p.supplier_id = s.supplier_id
WHERE
o.customer_id IN (SELECT customer_id FROM RecentCustomers)
GROUP BY
s.supplier_name, o.order_id, o.amount
WHERE
AVG(o.amount) > 100
)
SELECT
Supplier_Name,
AVG(Amount) AS Avg_Order_Value
FROM
SupplierOrderValues
GROUP BY
Supplier_Name;</xmp>
ניתוח והסבר Execution Plans
כשאנחנו מתמודדים עם שאילתה שרצה לאט, ניתן להבין למה באמצעות ה-Execution Plan שהמערכת יצרה – קובץ טקסט או עץ מורכב שמספר לנו איך הדאטהבייס מתכוון לבצע את הקוד (Estimated) או איך הוא בפועל הריץ אותו (Actual).
הבעיה היא שתוכניות ביצוע הן לרוב ארוכות, טכניות וקשות מאוד להבנה, שלפענח אותם זו התמחות בפני עצמה.
אני לא חושב שה-AI לא יכול להחליף את ה DBA או ה BI Developer / Data Engineer שיודעים לפענח את התוכניות האלו לעומק וגם מכירים את הארכיטקטורה של ה DB בצורה יסודית. אבל במקרים רבים, פשוטים יותר – הוא לגמרי יכול לשמש כמתרגם: במקום שננסה להבין מה בדיוק אומרת השורה "Nested Loop Inner Join" או "Clustered Index Seek", אנחנו יכולים להדביק את תוכנית הביצוע ל-AI ולבקש ממנו:
לזהות את צווארי הבקבוק: היכן המערכת מבזבזת הכי הרבה זמן? האם זה ב-
JOINמסוים, בחיפוש בטבלה גדולה, או בפונקציה שלוקחת המון משאבים?לפשט את המידע: לבקש ממנו להסביר את תוכנית הביצוע בשפה פשוטה או לסכם את "תוכנית הביצוע" ב-X נקודות מרכזיות.
המרת דיאלקטים שונים של SQL
בעולם הדאטה ישנם דיאלקטים רבים ל-SQL (PostgreSQL, MySQL, SQL Server, BigQuery, Snowflake, ועוד). שאילתה שנכתבת עבור בסיס נתונים אחד, עשויה להיכשל באחר.
ה-AI מצוין בתרגום דיאלקטים. הוא יכול לקבל שאילתה ב-TSQL (של SQL Server) ולתרגם אותה ל-PL/pgSQL (של PostgreSQL), תוך שהוא מתחשב בהבדלים סינטקטיים, בפונקציות תאריך שונות או באופן שבו הוא מטפל במשתנים או טבלאות זמניות.
תיעוד אוטומטי של לוגיקה עסקית
לעתים קרובות אנחנו יורשים שאילתות או תהליכי ETL מורכבים שאף אחד לא טרח לתעד. מהנסיון שלי – כמויות הזמן שאנשים מבזבזים בלהבין איך לוגיקה עסקית כלשהי עובדת, במקום להיות פרודוקטיביים, עצומה. במקום לבנות דוח שמבקשים ממך, או לטפל בבקשה לתהליך ETL חדש – אתה יום שלם (במקרה הטוב) יושב ומנסה להבין מה הבחור/ה שלפניך כתבו, ואיך הקוד הזה עובד.
עכשיו – לרוב אף אחד לא מעוניין להתעסק עם תיעוד, ובניית דוקומנטציות, לרוב – אנשים מתרצים את זה שהם לא מסבירים ומתעדים את מה שהם עשו כי זה ״יקח המון זמן ויש עוד מלא משימות״. אבל היום אין שום סיבה שזה לא יהיה סטנדרט בכל ארגון – להשקיע עוד כמה 10-20 דקות בתיעוד הקוד באמצעות ה-AI.
הוא יכול לקחת שאילתת SQL מורכבת ולהפוך אותה למסמך קריא שמסביר את הלוגיקה העסקית של הקוד:
ברמת הסיכום: במקום כלום, או לכתוב משהו גנרי כמו: "השאילתה מחברת את טבלת A עם B", ה-AI יכול לכתוב: "הדוח הזה מחשב את מדד שיעור הנטישה (Churn Rate) על ידי ספירת לקוחות שלא ביצעו הזמנה ב-90 הימים האחרונים (מתוך ה-CTE
RecentOrders)."ברמת ה Data Lineage: בייחוד במערכות גדולות, ה-AI יכול לנתח מאיזה טבלאות מקוריות נלקחים הנתונים, מהם שלבי הטרנספורמציה (סינונים, קיבוצים), איך הם משפיעים על הפלט הסופי, ולתעד הכל עבור הדורות הבאים שיעבדו עם המערכות הללו.
ברמת הסטנדרט ל-KPIs השונים: ה-AI יכול לעבור על שמות העמודות בשאילתה ולהציע הגדרות סטנדרטיות לכל מדד חדש שנוצר (למשל,
total_revenue_ytd), מה שיכול לסייע רבות ליצירת שפה אחידה בארגון.
יצירת Mock Data לסביבות בדיקה
כדי לבדוק שאילתה מורכבת או מנגנון ETL חדש, אנחנו זקוקים לנתוני דוגמה (Mock Data) שמשקפים את הבעיות שאנו מנסים לפתור, מבלי לעבוד ישירות על נתוני Production.
ה-AI הוא כלי מושלם ליצירת סביבות בדיקה זמניות:
יצירת DDL מלא: על בסיס פרומפט קצר, ה-AI יכול ליצור את פקודת
CREATE TABLEהמלאה כולל סוגי נתונים, ו-Constraints.הזנת נתונים סינתטיים: ה-AI יכול ליצור אוטומטית פקודות
INSERT INTOעם נתונים אקראיים אך הגיוניים. לדוגמה, לבקש ממנו ליצור 100 שורות המדמות "לקוחות" עם 80% מארה"ב, 20% מגרמניה, ו-5% מתוכם עם סך הזמנות מעל 1,000 ש"ח.בדיקת תרחישי קצה: ניתן לבקש מה-AI ליצור שורות נתונים ספציפיות המדמות תרחישים נדירים (כגון שורות עם ערכי
NULLחסרים או תאריכים שגויים), כדי שנוכל לבדוק שהשאילתה שלנו מטפלת בהם בצורה נכונה.
שני טיפים לגבי הנושא הזה:
- אל תבקשו ממנו ליצור לכם משפטי INSERT פשוטים, כי אם תבקשו מאות או אלפי שורות – הוא יקרוס מהר מאוד, במקום זה עדיף שיצור לכם סקריפט פיתון בסיסי שיוצר את אותן שורות.
- אם אתם מתעניינים בדאטה-סט סינטטי פשוט (בלי התפלגויות מורכבות), במקום הצ׳ט אולי שווה לכם לעבוד עם כלים כמו Mockaroo
הצד השני של המטבע
כן, שמעתם את זה כבר מלא פעמים. אבל אי אפשר לסיים פוסט כזה בלי לכתוב את הוראות ההפעלה הבסיסיות: ה-AI הוא כלי עזר מדהים, אבל הוא רחוק מלהיות חסין טעויות, והוא לא מחליף את ההבנה האנושית של הדאטה והביזנס. כדי להשתמש בו נכון, יש לשים לב למגבלות הבאות:
ידע ב-SQL: אם אתם עושים קופי-פייסט למה שהצ׳ט נתן לכם בלי להבין מה בדיוק הוא עושה – אתם מסתכנים. לפעמים הוא הוזה בהקיץ, הוא ממציא דברים, הוא עלול לא להבין אתכם, ויכול לכתוב דברים שיעשו יותר נזק מתועלת.
הצורך בביקורת אנושית: בהמשך לסעיף הקודם, ה-AI עדיין יכול "להמציא" שמות טבלאות או עמודות שאינן קיימות, לייצר לוגיקה עסקית שגויה, או להציע שאילתות לא יעילות או אובר-מורכבות. חובה להפעיל ביקורת על כל פיפס שהוא כותב, זה נהדר שהוא עושה לנו את כל ה Heavy Lifting, אבל זה לא חוסך את שיקול הדעת שלנו.
הבעיה של 'Garbage In, Garbage Out': ככל שהפרומפט (או הקוד המוזן) שלכם מעורפל יותר, כך סביר יותר שהתשובה תהיה שגויה. אם לא מספקים את מבנה הטבלה, מטרת השאילתה, או את הקשר עסקי ברור, ה-AI עשוי לשער השערות על דעת עצמו, ולהוביל לטעויות. הדיוק של הפלט תלוי ישירות באיכות הקלט.
זה לוקח כמה איטרציות: ברוב המקרים לא מקבלים תשובה מושלמת בפעם הראשונה. צריך לדעת לשאול שוב, לדייק את הפרומפט, ולכוון את ה־AI (תודה למשה יוסף על הטיפ המצויין)
בקשו יותר מחלופה אחת – כשמבקשים מה־AI לכתוב שאילתה, כדאי לבקש כמה גישות שונות ולבחור את הטובה ביותר. זה מונע להיתקע על פתרון יחיד שעשוי להיות לא מיטבי. (ושוב – תודה למשה יוסף על עוד טיפ מעולה)
ביצועים ויעילות שאילתות: ה־AI לא בהכרח מייצר קוד יעיל. לעיתים קרובות השאילתות שהוא כותב לא מנצלות אובייקטים שונים ב-Database כדי ליצור שאילתה בעלת ביצועים אופטימליים. לכן, גם אם הלוגיקה נכונה – הביצועים שלה עלולים להיות יקרים.
כשזה נוגע לכתיבה מ-0, השימוש ב־AI מתאים בעיקר לשלב הפיתוח המוקדם: כתיבת טיוטה, ניסוי וטעייה, או ייצור קוד מהיר לבדיקת רעיונות. אבל כשעובדים עם דאטה אמיתי בפרודקשן -מומלץ שמומחה SQL יעבור על הקוד ויבצע אופטימיזציה אמיתית.
תודה לברק על הטיפ המצוייןוכמובן – אבטחת מידע: כאשר אתם מזינים ל-AI קוד המכיל שמות של טבלאות, עמודות או נתונים ספציפיים, אתם בעצם משתפים פרטים על המבנה הפנימי של מסד הנתונים שלכם. צריך להשתמש בזהירות ובתהליכים זהירים ומאושרים על ידי הארגון, וכמובן להימנע מהזנת נתונים רגישים.
לסיכום
ה-AI משנה את הדרך שבה אנחנו כותבים ועובדים עם SQL. הוא יודע לשכתב "מפלצות" של קוד, למצוא בעיות, לתרגם בין דיאלקטים שונים ואפילו לעזור להבין Execution Plans.
בעזרת ה-AI אנחנו שומרים על סטנדרטים גבוהים יותר, מאמצים Best Practices וחושבים על פתרונות יעילים יותר. אבל חשוב לזכור – ה-AI דורש פרומפטים מדויקים וביקורת אנושית. צורת העבודה החדשה מאתגרת אותנו לעבוד חכם יותר, לא קשה יותר.