חורף 2008-9dbms - 236363, שפות שאילתה: sql 1 sql questions

27
ףףףף2008-9 DBMS - 236363, :ףףףף ףףףףףףSQL 1 SQL questions

Post on 21-Dec-2015

224 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 1

SQL questions

Page 2: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

: מציאת שמות לא 1שאלה יחודיים

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 2

נתונה הסכמה:Customers(Cust_Id, Cust_Name, Faculty)

המטרה: למצוא כמה שמות לא ייחודיים )כפולים( ישנם

במערכת.

Page 3: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

: מציאת שמות לא 1שאלה יחודיים

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 3

Customers(Cust_Id, Cust_Name, Faculty)

SELECT COUNT (Cust_Name) AS resFROM Customers AS c1WHERE EXISTS

(SELECT 1 FROM Customers AS c2WHERE c1.Cust_Name = c2.Cust_Name);

?SELECT 1מדוע ביצענו •Existsכי אין צורך במידע עצמו עבור •

האם השאילתא תחזיר את המידע הרצוי?•לא, היא תחזיר את מספר השמות שישנם במערכת )כל רשומה מקיימת •

כאשר אנו מצליבים אותה עם עצמה(Existsאת התנאי בתוך ה-

Page 4: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

: מציאת שמות לא 1שאלה יחודיים

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 4

Customers(Cust_Id, Cust_Name, Faculty)

SELECT COUNT (DISTINCT Cust_Name) AS resFROM Customers AS c1WHERE EXISTS

(SELECT 1 FROM Customers AS c2WHERE c1.Cust_Name = c2.Cust_NameAND c1.Cust_Id <> c2.Cust_Id);

בשביל לא לספור רשומות DISTINCTיש צורך ב-פעמיים

Page 5: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

VIPs: מציאת 2שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 5

נתונה הסכמה:Borrowed(Book_Id, Cust_Id, From_Date, To_Date)

המטרה: למצוא כמה מהלקוחות שאלו יותר ספרים מהממוצע.

Page 6: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

VIPs: מציאת 2שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 6

נתונה הסכמה:Sale(Cust_Id, qty, amount)

המטרה: למצוא כמה לקוחות קנו באחת הפעמים יותר מהכמות הממוצעת במכירה.

SELECT COUNT(DISTINCT Cust_Id)FROM SaleGROUP BY Cust_IdHAVING AVG(qty) < qty;

תקין?• HAVING ב-qty – לא ניתן להתייחס ל-Syntaxלא תקין אפילו מבחינת •

(AVG(qty)כאשר לא קיבצנו לפיו )לעומת זאת ניתן להתייחס ל-AVG(qty) הרי שלא נוכל להתייחס ל-qtyאם נקבץ לפי • על-מנת לחשב את הממוצעsubqueryיש צורך ב-•

HAVING (SELECT AVG(qty) FROM Sale) < qty

Page 7: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

: תנאים מורכבים3שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 7

נתונה הסכמה:Customers(Cust_Id, Cust_Name, Faculty)Borrowed(Book_Id, Cust_Id, From_Date, To_Date)Excellent(Cust_Id, Semester, Type)

כאשר הרלציה הראשונה והשנייה הן אלו המוכרות לנו, והשלישית מתארת הצטיינויות סטודנטים.

המטרה: 10למצוא כמה סטונדטים הם מצטיינים או לוו יותר מ-

ספרים. כיצד כדאי לעשות זאת?

Page 8: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

1 : ניסיון3שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 8

:1אפשרות SELECT t2.tot + t3.totFROM

(SELECT COUNT(t1.Cust_Id) FROM(SELECT Borrowed.Cust_Id as totFROM Borrowed GROUP BY Borrowed.Cust_Id HAVING COUNT(Borrowed.Cust_Id)>10) AS t1)AS t2,

(SELECT COUNT(Excellent.Cust_Id) as totFROM Excellent) AS t3

הרעיון:• t2 ספרים10 מחזירה את הסטודנטים ששאלו מעל •t3 מחזירה את מספרם של סטודנטים אלו • t1מחזירה את מספר המצטיינים

תקין?באילו בעיות אנו עלולים להיתקל?

Page 9: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

2 : ניסיון3שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 9

:2אפשרות SELECT Customers.Cust_Id,

COUNT(DISTINCT Excellent.Cust_Id) +COUNT(DISTINCT t1.Cust_Id) AS totStudents

LEFT OUTER JOIN ExcellentON Customers.Cust_Id=Excellent.Cust_Id

LEFT OUTER JOIN(SELECT DISTINCT Borrowed.Cust_IdFROM Borrowed GROUP BY Borrowed.Cust_IdHAVING COUNT (Borrowed.Cust_Id)>10 ) AS t1ON t1.Cust_Id=Excellent.Cust_IdAND COALESCE(Excellent.Cust_Id, -1)<>t1.Cust_Id

GROUP BY Customers.Cust_Id

נבחר רק סטודנטים שאינם מצטיינים Borrowedהרעיון – מהטבלה

Page 10: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

2 : ניסיון3שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 10

הכרחי?DISTINCTהאם ה-• - כן, סטודנטים יכולים להצטיין ביותר מסמסטר אחדExcellentעבור •Cust_Id על-פי GROUP BY – לא, ביצענו כבר Borrowedעבור • עלולות מספר t1 תיצור כפילויות )עבור רשומה אחת מ-Join – כן, פעולת ה-t1עבור •

להיות תואמות(Excellentרשומות מ-

? COALESCEלמה אנו צריכים • כל פעולה עליהם COALESCE וללא LEFT OUTER JOIN בפעולת NULLייתכנו ערכי •

FALSE ואינו TRUE שאינו NULLתחזיר

האם ספרנו סטודנטים פעמיים?•לא – הורדנו את החיתוך באמצעות התנאי•

COALESCE(Excellent.Cust_Id, -1)<>t1.Cust_Id לא חוקי(ID- הוא 1אם הסטודנט הצטיין התנאי לא מתקיים )בהנחה ש-

מתבצעת למרות שעבור רשומה t1.Cust_Id=Excellent.Cust_Idתקין? כמעט, אבל לא. ההשוואה • – Customers.Cust_Id=Excellent.Cust_Id המקיימת Excellent-יה ב-nמסוימת ייתכן שלא קיימת

המושווה עלול להיות Excellent.Cust_Idשהוא תנאי קודם )כי הסטודנט אינו מצטיין(. מכאן ש-NULL ולא יתקיים t1.Cust_Id=Excellent.Cust_Id.

t1.Cust_Id=Customer.Cust_Idהיה צריך להיות

Page 11: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

3 : ניסיון3שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 11

:3אפשרות SELECT COUNT(t1.Cust_Id)FROM

(SELECT Cust_Id From ExcellentUNION SELECT Cust_Id FROM Borrowed GROUP BY Cust_IdHAVING Count(Cust_Id)>10) AS t1

?DISTINCTהאם יש צורך ב-• תוריד את כל האיברים הלא ייחודייםUNIONלא – פעולת ה-•

תקין? •כן...•

Page 12: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

: מציאת מחיר4שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 12

עבור חברה המוכרת פריט בודד מוגדרת הסכמה הבאה:

Sales(Qty, Price, Time)

הפריטים 100יש למצוא את המחיר הממוצע של (.100הראשונים )נניח שנמכרו יותר מ-

האם יש איזשהו קושי?

Page 13: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

: הקושי4שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 13

המכירות הראשונות xהקושי: ייתכן שאם נסכום את • x+1 פריטים אך כאשר נסכום את 100נקבל מתחת ל-

פריטים.100המכירות הראשונות נקבל מעבר ל-

QtyPriceTime

901002007-01-01

82002008-01-01

101002009-01-01

Page 14: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

1: שלב 4שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 14

המגדיר לכל תאריך מבין תאריכי המכירה – כמה totSales: ניצור מבט 1שלב •פריטים נמכרו עד אותו התאריך ומה היה סך מחיריהם.

CREATE VIEW totSales AS SELECT t1.time, SUM(t2.price) AS totPrice, SUM(t2.qty) AS totQtyFROM Sales AS t1, Sales AS t2WHERE t2.time <= t1.timeGROUP BY t1.time;

-יה במבט תעניין אותנו?nאיזו בהמשך...•

Page 15: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

א1: שלב 4שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 15

בפועל בשביל החישוב, אנו זקוקים למידע נוסף:•

CREATE VIEW totSales AS SELECT t1.time, t1.price, t1.qty, SUM(t2.price) as totPrice, SUM(t2.qty) AS totQtyFROM Sales AS t1, Sales AS t2WHERE t2.time <= t1.timeGROUP BY t1.time, t1.price, t1.qty;

Page 16: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

2: שלב 4שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 16

-יה שתעניין אותנו.nכעת עלינו להחליט מהי ה-•-יה שמספר הפריטים שנמכרו עד לאותו nתהיה זאת ה-•

– נבחר אותה מהמבט שיצרנו.100הזמן גדול-שווה ל-

SELECT t1.time, t1.price, t1.qty, t1.totPrice, t1.totQtyFROM totSales AS t1WHERE NOT EXISTS

(SELECT 1 FROM totSales AS t2 WHERE t2.totQty>=100 AND t2.time<t1.time);

Page 17: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

: שלב אחרון4שאלה

2008-9חורף DBMS - 236363, שפות שאילתה: SQL 17

-יה את nכל שנותר הוא לחשב על-ידי המידע ב-•החישוב הנחוץ:

SELECT (t1.totPrice-t1.price*(t1.qty-100))/100 as res

FROM totSales AS t1WHERE NOT EXISTS

(SELECT 1 FROM totSales AS t2 WHERE t2.totQty>=100 AND t2.time<t1.time);

Page 18: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

5שאלה

:נתון מסד נתונים למערכת השכרת רכבCars: {CarNumber, Brand, Year, Miles, DailyCharge}Customer: {CustomerLicenseNo, CustomerName}Rent: {CustomerLicenseNo, CarNumber, RentingStartDate}

:הסבר למסד הנתוניםCars( טבלת מכוניות. לכל מכונית נשמרים מספר זיהוי הרכב :CarNumber ,)

(, מספר הקילומטרים שנסעו בו Year(, שנת הייצור )Brandסוג הרכב )(Miles( ומחיר ההשכרה ליום )DailyCharge.)

Customer טבלת לקוחות. לכל לקוח נשמר נשמרים מס' רשיון הנהיגה של :(. בנוסף, נשמר שם הלקוח )או החברה(. נניח CustomerLicenseNoהנהג ) (. CustomerName לקוחות עם אותו השם )2כי אין

Rent טבלת השכרות רכב. עבור כל השכרה נשמרים מס' רשיון הנהיגה של :(.(RentingStartDateהנהג, מס' זיהוי הרכב ותאריך התחלת ההשכרה

Page 19: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

:SQLכתבו את השאילתה הבאה ב-1.עבור כל לקוח, החזירו את התעריף היומי הממוצע ששילם עבור כל

השכרה. החזירו את מספר רשיון הנהיגה של הלקוח ואת התעריף הממוצע.

.0עבור לקוחות שלא השכירו רכבים יש להחזיר את המספר

דגשים: הלקוחותכליש להחזיר את ?מה עושים עם לקוחות שלא השכירו רכבים

SELECT Customer.CustomerLicenseNo,

COALESCE)AVG) DailyCharge(, 0(FROM )Customer LEFT OUTER JOIN Rent ON

)Customer.CustomerLicenseNo = Rent.CustomerLicenseNo(( LEFT OUTER JOIN Cars ON

)Rent.CarNumber = Cars.CarNumber(GROUP BY Customer.CustomerLicenseNo

Page 20: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

:SQL. כתבו את השאילתה הבאה ב-2 ק"מ, 100 לכל דגם של מכונית, כך שבכל מכונית מדגם זה נסעו לפחות

החזירו את מספר הלקוחות השונים ששכרו דגם זה ושמם מכיל את המילה

"David" . דגשים:

?איך מחזירים רק את הדגמים מתאימיםCREATE VIEW lessThen100 ASSELECT brand FROM CarsGROUP BY brandHAVING MIN)Miles(<100

:השאילתהSELECT Brand, COUNT) DISTINCT CustomerLicenseNo(FROM Cars C, Rent, CustomerWHERE Brand NOT IN lessThen100 AND Cars.CarNumber = Rent.CarNumber AND Rent.CustomerLicenseNo = Customer.CustomerLicenseNo AND CustomerName LIKE %David%GROUP BY Brand

Page 21: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

. מה מחזירה השאילתה:3

SELECT DISTINCT Rent. CustomerLicenseNo, Rent.CarNumber

FROM RentWHERE )EXISTS )SELECT COUNT)*(

FROM Rent AS MultRentWHERE MultRent.CustomerLicenseNo

= Rent.CustomerLicenseNo

GROUP BY MultRent.CarNumberHAVING Count)*( > 1((;

כל הזוגות של נהג ומספר מכונית כך שהנהג שכר את המכונית וגם הנהג שכר מכונית כלשהי לפחות פעמיים

Page 22: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

:SQL. כתבו את השאילתה הבאה ב-4 עבור כל לקוח )בסדר עולה של שם לקוח( ששכר אי פעם רכב שמספר הקילומטרים

שלו )כיום( גבוה מממוצע הקילומטרים של הרכבים הנמצאים בבסיס הנתונים )כיום(, מצא

את הקילומטרז' של הרכב בעל הקילומטרז' המינימלי שהוא שכר.

החזירו את שמות הלקוחות ואת הקילומטראז'.

SELECT CustomerName, min)miles(FROM Customers, Cars, RentWHERE Customers.CustomerLicenseNo = Rent.CustomerLicenseNoAND Cars.CarNumber = Rent.CarNumberAND Customers.CustomerLicenseNo IN

)SELECT Customers.CustomerLicenseNoFROM Rent, Cars, CustomersWHERE Customers.CustomerLicenseNo = Rent.CustomerLicenseNoAND Cars.CarNumber = Rent.CarNumberAND Cars.Miles > )SELECT Avg)Miles( FROM Cars((

GROUP BY Customers.CustomerNameORDER BY Customers.CustomerName;

Page 23: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

השאלה הבאה מתייחסת לרלציה Books)Book_Id, Book_Name, Faculty(.נתונה השאילתא הבאה:

SELECT B1.Faculty, COUNT )B1.Faculty( /

)COUNT )DISTINCT B1.Book_Id( - 1(FROM Books B1, Books B2WHERE B1.Faculty = B2.Faculty

AND B1.Book_Id <> B2.Book_IdGROUP BY B1. Faculty;

6שאלה

Page 24: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

מה מחזירה השאילתא עבור התוכן הבא של טבלת Books:

Book_idBook_NameFaculty

1Database SystemsCS

2SQLCS

3Database SystemsCS

4Electronic CircuitsEE

(1דוגמה – פתרון)

Page 25: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

(2דוגמה – פתרון)

לאחר הפעלתjoin ותנאי WHERE:נקבל

Book_id1Book_Name1Faculty1Book_id2Book_Name2Faculty2

1Database SystemsCS2SQLCS

1Database SystemsCS3Database SystemsCS

2SQLCS1Database SystemsCS

2SQLCS3Database SystemsCS

3Database SystemsCS2SQLCS

3Database SystemsCS1Database SystemsCS

Page 26: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

הסבר: קיבלנו עבור כל הקבצה של ספרים מאותהפקולטה, את כל הזוגות הסדורים השונים האפשריים של

יופיע >a,a<ספרים )שונים במובן שלא ייתכן שהזוג (.joinבתוצאת ה-

לכן, אם בפקולטה מסוימת ישN -ספרים שונים כך ש N>1 אזי בהקבצה של הפקולטה הזו נקבל ,N*)N-1(

רשומות )מספר הזוגות האפשריים(

(3דוגמה – פתרון)

Page 27: חורף 2008-9DBMS - 236363, שפות שאילתה: SQL 1 SQL questions

:תוצאה סופית

.כתבו במילים מה משמעות השאילתא ,תשובה: לכל פקולטה שיש בה יותר מספר אחד

מוחזר שם הפקולטה ומספר הספרים )השונים( שנמצאים בה.

(4דוגמה – פתרון)

FacultyCount…

CS3