Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Advanced SQL Webinar

December 2016

  • Be the first to comment

Advanced SQL Webinar

  1. 1. Advanced SQL - Tips & Tricks Ram kedem
  2. 2. About Me • Data Team Leader at PLYmedia • During the last decade trained thousands of people (Israel and abroad) various topic related to the database world. • Managing an educational website mainly focused on the SQL language • Owner of Ram Kedem Training
  3. 3. About this Book • Gathered over a period of almost 10 years • Includes 265 pages and 100 Different complex SQL use-cases • First of its kind in Israel • Aims to provide practical knowledge based on real user experience • Available in Hard-Copy & Online version
  4. 4. Goals • Learn real use cases of : • Advanced Scalar Functions • Analytic Functions • Group Functions • Complex Sub-Queries • CTE and Recursive CTE • SET Operators • XML tricks
  5. 5. ‫שונים‬ ‫פורומים‬ ‫המנהל‬ ‫אינטרנט‬ ‫לאתר‬,‫שונים‬ ‫משתמשים‬ ‫של‬ ‫ההודעות‬ ‫תוכן‬ ‫את‬ ‫המכילה‬ ‫טבלה‬ ‫קיימת‬. ‫אפליקצייה‬ ‫שגיאות‬ ‫בשל‬ ‫לעיתים‬,‫סימני‬ ‫נכנסים‬ ‫המלל‬ ‫בתוך‬% ‫שונות‬ ‫טכניקות‬ ‫שתי‬ ‫באמצעות‬,‫אחוז‬ ‫מכילים‬ ‫אשר‬ ‫הערכים‬ ‫את‬ ‫מצאו‬)%( 1.‫אחוז‬ ‫עם‬ ‫ערכים‬ ‫מציאת‬
  6. 6. 1.‫אחוז‬ ‫עם‬ ‫ערכים‬ ‫מציאת‬ • escape_character • Is a character that is put in front of a wildcard character to indicate that the wildcard should be interpreted as a regular character and not as a wildcard. • escape_character is a character expression that has no default and must evaluate to only one character SELECT * FROM percent_values WHERE id LIKE '%^%%' ESCAPE '^'
  7. 7. 1.‫אחוז‬ ‫עם‬ ‫ערכים‬ ‫מציאת‬ • Using square brackets • In MSSQL the square brackets are required if you use keywords or special chars in the column names or identifiers. • For example, You could name a column [First Name] (with a space) • The [ ] in LIKE can be used to specify the % should to be interpreted as a regular character SELECT * FROM percent_values WHERE id LIKE '%[%]%'
  8. 8. 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬ ‫הבאות‬ ‫הטבלאות‬ ‫נתונות‬: ‫לקוחות‬ ‫טבלת‬,‫מס‬ ‫לגבי‬ ‫תיאור‬ ‫למצוא‬ ‫ניתן‬ ‫שורה‬ ‫בכל‬'‫הלקוח‬, ‫שמו‬,‫ומס‬'‫מתגורר‬ ‫הוא‬ ‫בה‬ ‫העיר‬ ‫ערים‬ ‫טבלת‬,‫עבור‬ ‫הערים‬ ‫שמות‬ ‫את‬ ‫למצוא‬ ‫ניתן‬ ‫זו‬ ‫בטבלה‬ ‫הלקוחות‬ ‫טבלת‬
  9. 9. 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬ ‫העיר‬ ‫את‬ ‫תציג‬ ‫שורה‬ ‫בכל‬ ‫אשר‬ ‫שאילתה‬ ‫כתבו‬,‫בה‬ ‫מתגוררים‬ ‫אשר‬ ‫השונים‬ ‫הלקוחות‬ ‫ואת‬
  10. 10. 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬ STUFF() Function • The STUFF function deletes a sequence of characters from a source string and then inserts another sequence of characters into the source string, starting at a specified position. SELECT STUFF('Hello' , 1,1,'B') => Bellow SELECT STUFF('Hello' , 1,2,'B') => Bllo SELECT STUFF('Hello', 2, 2, '**WORLD**') => H**WORLD**lo SELECT STUFF('Hello', 1, 1, '') => ello
  11. 11. Correlated Sub Queries VS. Simple Sub Queries • Correlated Subquery is a sub-query that uses values from the outer query. the inner query has to be executed for every row of outer query • Simple subquery doesn't use values from the outer query and is being calculated only once 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬
  12. 12. Simple Sub Query SELECT customerName, CityID FROM customers WHERE CityID = (SELECT cityID FROM cities WHERE CityName = 'Tel Aviv') • Inner – what’s the cityID of Tel Aviv ? (only once) • Outer – Display the customerName and CityID for customers whose CityID equals to the output of inner query 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬
  13. 13. Correlated Sub Query SELECT CUST.CustomerName, (SELECT CityName FROM Cities CT WHERE CT.CityID = CUST.CityID) FROM customers CUST • Inner – what’s the cityName for the FIRST row in the table ? • Outer – Display the customerName in the FIRST row • Inner – what’s the cityName for the SECOND row in the table ? • Outer – Display the customerName in the SECOND row … 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬
  14. 14. For XML Path 1. Get XML element string with FOR XML • Adding FOR XML PATH to the end of a query allows you to output the results of the query as XML elements, with the element name contained in the PATH argument SELECT ',' + CustomerName FROM Customers FOR XML PATH ('') 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬
  15. 15. For XML Path 2. Remove leading comma with STUFF • The STUFF statement literally "stuffs” one string into another, replacing characters within the first string. We, however, are using it simply to remove the first character of the resultant list of values. SELECT STUFF ( (SELECT ',' + CustomerName FROM Customers FOR XML PATH ('')) ,1,1,'' ) 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬
  16. 16. Putting it all together SELECT CityID, CityName, STUFF ( (SELECT ',' + CustomerName FROM Customers InCust WHERE InCust.CityID = CT.CityID FOR XML PATH ('')) ,1,1,'' ) AS 'Customers' FROM Cities CT 2.‫אחת‬ ‫שורה‬ ‫לתוך‬ ‫ערכים‬ ‫איחוד‬
  17. 17. ‫אות‬ ‫לפי‬ ‫מקובצות‬ ‫מסויים‬ ‫במשפט‬ ‫האותיות‬ ‫כמות‬ ‫את‬ ‫מחזירה‬ ‫אשר‬ ‫שאילתה‬ ‫כתבו‬,‫צמד‬ ‫עבור‬ ‫לדוגמא‬ ‫המילים‬: ‫הבאה‬ ‫התוצאה‬ ‫תתקבל‬ 3.‫במשפט‬ ‫תווים‬ ‫כמות‬ ‫הצגת‬
  18. 18. CTE Basics • A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement • Using a CTE offers the advantages of improved readability and ease in maintenance of complex queries. • The query can be divided into separate, simple, logical building blocks. These simple blocks can then be used to build more complex, interim CTEs until the final result set is generated. 3.‫במשפט‬ ‫תווים‬ ‫כמות‬ ‫הצגת‬
  19. 19. ;WITH [CountCustomers] (col1, col2) AS ( SELECT COUNT(*) CNT , CityID FROM customers GROUP BY CityID ) SELECT * FROM [CountCustomers] 3.‫במשפט‬ ‫תווים‬ ‫כמות‬ ‫הצגת‬ CTE name Column names CTE name Actual Query
  20. 20. ;WITH "Numbers" (id) AS ( SELECT 1 UNION ALL SELECT id + 1 FROM "Numbers" WHERE id < 20 ) SELECT * FROM "Numbers" 3.‫במשפט‬ ‫תווים‬ ‫כמות‬ ‫הצגת‬ CTE name Column name CTE name Anchor query (runs once and the results ‘seed’ the Recursive query) Recursive query (runs multiple times and is the criteria for the remaining results) UNION ALL statement to bind the Anchor and Recursive queries together.
  21. 21. WITH "wordlen"(id) AS ( SELECT 1 UNION ALL SELECT id + 1 FROM "wordlen" WHERE id < (SELECT LEN('hello world')) ) SELECT letter, COUNT(letter) FROM ( SELECT SUBSTRING('hello world' , id , 1) letter FROM "wordlen" WHERE SUBSTRING('hello world' , id , 1) <> ' ' ) in_tab GROUP BY letter ORDER BY letter 3.‫במשפט‬ ‫תווים‬ ‫כמות‬ ‫הצגת‬
  22. 22. ‫שונים‬ ‫יוזרים‬ ‫של‬ ‫המלאים‬ ‫שמותיהם‬ ‫את‬ ‫המכילה‬ ‫טבלה‬ ‫נתונה‬(‫פרטי‬ ‫שם‬,‫אמצעי‬ ‫שם‬,‫משפחה‬ ‫ושם‬.)‫ליוזרים‬ ‫אמצעי‬ ‫שם‬ ‫קיים‬ ‫לא‬ ‫מסויימים‬,‫בלבד‬ ‫משפחתו‬ ‫ושם‬ ‫הפרטי‬ ‫שמו‬ ‫יופיעו‬ ‫אלו‬ ‫במקרים‬.‫את‬ ‫עדכן‬ ‫לא‬ ‫יוזר‬ ‫לעיתים‬ ‫משפחתו‬ ‫שם‬ ‫ואת‬ ‫האמצעי‬ ‫שמו‬,‫בלבד‬ ‫הפרטי‬ ‫שמו‬ ‫יופיע‬ ‫אלו‬ ‫במקרים‬. 4.‫בעמודה‬ ‫מילים‬ ‫פיצול‬
  23. 23. ‫הפרטי‬ ‫שמו‬ ‫את‬ ‫שונות‬ ‫בעמודות‬ ‫המציגה‬ ‫שאילה‬ ‫כתבו‬,‫האמצעי‬ ‫שמו‬,‫מהיוזרים‬ ‫אחד‬ ‫כל‬ ‫של‬ ‫משפחתו‬ ‫ושם‬. ‫האמצעי‬ ‫והשם‬ ‫במידה‬‫מופיע‬ ‫לא‬ ‫המשפחה‬ ‫שם‬,‫יוצג‬NULL. 4.‫בעמודה‬ ‫מילים‬ ‫פיצול‬
  24. 24. REVERSE () • Returns the reverse order of a string value. • SELECT REVERSE('Hello') => 'Olleh' REPLACE () • Replaces all occurrences of a specified string value with another string value. • SELECT REPLACE('Hello World','World','SQL') => 'Hello SQL' PARSENAME () • Returns the specified part of an object name • SELECT PARSENAME('Word1.Word2.Word3.Word4',1) => 'Word4' 4.‫בעמודה‬ ‫מילים‬ ‫פיצול‬
  25. 25. SELECT REVERSE('Hello,World') SELECT REPLACE(REVERSE('Hello,World'),',','.') SELECT PARSENAME(REPLACE(REVERSE('Hello,World'),',','.'),1) SELECT REVERSE(PARSENAME(REPLACE(REVERSE('Hello,World'),',','.'),1)) 4.‫בעמודה‬ ‫מילים‬ ‫פיצול‬ dlroW,olleH dlroW.olleH olleH Hello
  26. 26. SELECT FirstName, CASE WHEN lastName IS NULL THEN NULL ELSE MiddleName END AS MiddleName, CASE WHEN LastName IS NULL THEN MiddleName ELSE LastName END AS LastName FROM ( SELECT Reverse(ParseName(Replace(Reverse(username), ' ', '.'), 1)) As FirstName , Reverse(ParseName(Replace(Reverse(username), ' ', '.'), 2)) As MiddleName , Reverse(ParseName(Replace(Reverse(username), ' ', '.'), 3)) As LastName FROM users ) IN_TAB 4.‫בעמודה‬ ‫מילים‬ ‫פיצול‬ If there is no value in lastName then middleName is actually NULL If there is no value in lastName then middleName is actually lastName putting it all together
  27. 27. ‫הבאה‬ ‫הטבלה‬ ‫נתונה‬.‫במערכת‬ ‫תקלה‬ ‫התרחשה‬ ‫בהם‬ ‫תאריכים‬ ‫תיעוד‬ ‫למצוא‬ ‫ניתן‬ ‫זו‬ ‫בטבלה‬.‫כי‬ ‫לראות‬ ‫ניתן‬ ‫שגיאה‬ ‫בין‬1‫מס‬ ‫לשגיאה‬'2‫יומיים‬ ‫עברו‬,‫שגיאה‬ ‫בין‬2‫לשגיאה‬3‫עברו‬6‫ימים‬,‫הלאה‬ ‫וכן‬ ‫לשגיאה‬ ‫שגיאה‬ ‫בין‬ ‫הממוצע‬ ‫הימים‬ ‫מספר‬ ‫את‬ ‫מחזירה‬ ‫אשר‬ ‫שאילתה‬ ‫כתבו‬ 5.‫ממוצעים‬ ‫זמנים‬ ‫חישוב‬
  28. 28. 5.‫ממוצעים‬ ‫זמנים‬ ‫חישוב‬ LEAD() Function • LEAD provides access to a row at a given physical offset that follows the current row. Use this analytic function in a SELECT statement to compare values in the current row with values in a following row Basic Usage • LEAD(column_name) OVER (ORDER BY column_name)
  29. 29. 5.‫ממוצעים‬ ‫זמנים‬ ‫חישוב‬ Putting it all together SELECT AVG(DIFF) AVG_DIFF FROM ( SELECT id, fdate, ISNULL(DATEDIFF(day, fdate, LEAD(fdate) OVER (ORDER BY id)),0) DIFF FROM FailuresLog ) IN_TAB
  30. 30. ‫הבאה‬ ‫הצבעים‬ ‫טבלת‬ ‫נתונה‬,‫זוגי‬ ‫סידורי‬ ‫מספר‬ ‫תחת‬ ‫מופיעים‬ ‫הלבנים‬ ‫הצבעים‬ ‫כי‬ ‫לראות‬ ‫ניתן‬,‫והצבעים‬ ‫אי‬ ‫סידורי‬ ‫מספר‬ ‫תחת‬ ‫מופיעים‬ ‫השחורים‬-‫זוגי‬. ‫באמצעות‬6‫שונות‬ ‫טכניקות‬,‫הצבעים‬ ‫בין‬ ‫המחליפה‬ ‫שאילתה‬ ‫כתבו‬(‫מספר‬ ‫תחת‬ ‫יופיעו‬ ‫השחורים‬ ‫הצבעים‬ ‫זוגי‬ ‫סידורי‬,‫אי‬ ‫סידורי‬ ‫מספר‬ ‫תחת‬ ‫יופיעו‬ ‫הלבנים‬ ‫והצבעים‬-‫זוגי‬) 6.‫מותנית‬ ‫להחלפה‬ ‫מתודות‬
  31. 31. 6.‫מותנית‬ ‫להחלפה‬ ‫מתודות‬ -- 1. CASE SELECT cid, CASE WHEN cdesc = 'black' THEN 'white' ELSE 'black' END cdesc FROM colors -- 2. REPLACE SELECT cid, REPLACE (cdesc, 'black', 'white') FROM colors WHERE cdesc = 'black' UNION ALL SELECT cid, REPLACE (cdesc, 'white', 'black') FROM colors WHERE cdesc = 'white' ORDER BY 1 -- 3. IIF SELECT IIF(cdesc = 'white' , 'black' , 'white') FROM colors
  32. 32. 6.‫מותנית‬ ‫להחלפה‬ ‫מתודות‬ -- 4. SUBQUERY SELECT cid, (SELECT DISTINCT cdesc FROM colors in_tbl WHERE cdesc <> out_tbl.cdesc) FROM colors out_tbl -- 5. JOIN SELECT c1.cid, c2.cdesc FROM colors c1 JOIN (SELECT DISTINCT cdesc FROM colors) c2 ON c1.cdesc <> c2.cdesc ORDER BY 1 -- 6. ISNULL / NULLIF SELECT cid, ISNULL(NULLIF('white', cdesc), 'black') FROM colors
  33. 33. Advanced SQL Course • Will take place between March 21 and 28 at John-Bryce Tel-Aviv • 3 Meetings, 17:30-21:00 • More details can be found here
  34. 34. Thanks ! keep in touch Ram Kedem Facebook Linkedin