2012-01-09 153 views
1

我修改爲我的考試,我有點與SQL查詢掙扎..製作一個SQL查詢(交叉表)

工作對我來說是:

寫一個SQL查詢來列出所有客戶端的全名是 參加艾倫·摩爾的「S班,姓氏字母順序(即 lname列)

的Clie NT

Cid Fname Lname Fitness 
C129 Julie Summer 1 
C525 Max Hedrum 3 
C628 John Long 3 
C772 Warren Peace 2 
C829 Anna Heart 2 

計劃

Code Title Fitness 
AR02 Aerobics 2 
EN99 Endurance 3 
TU10 Tune-Up 1 
UB01 Upper-Body 2 
YG02 Yoga 1 

員工

Sid Fname Lname Position Salary 
S09 Jenny Sayer Psychologist 23500 
S22 Allen Moore Instructor 21500 
S28 Polly Purves Instructor 19000 
S35 Jim Shoe Instructor 18000 
S55 Mark Spencer Manager 25500 

Code Sid Cid 
AR02 S35 C772 
EN99 S22 C525 
TU10 S35 C129 
UB01 S28 C628 
YG02 S22 C829 
YG02 S22 C12 

它是這樣的:

SELECT Cliente.Fname, Cliente.Lname 
FROM Staff, Class, Cliente 
WHERE Staff.Sid = Class.Sid AND Staff.Fname = "Allen" AND Staff.Lname = "Moore 
AND Class.Cid = Cliente.Cid 
GROUP BY Cliente.lName ASC; 

謝謝!

+2

您將要使用'order by'而不是'group by'。最好是專門使用連接而不是from中的所有連接。 – Kyra 2012-01-09 20:05:52

+2

不公平的投票 - 這個問題很簡單但合理,努力找到答案。 – 2012-01-09 20:17:49

+0

表名中有Cliente(法語?)與Client的小問題。 GROUP BY是不正確的(它應該列出兩個列,因爲它們不是聚合的,然後它不會造成任何傷害,除了可能慢一點的事情;它不保證輸出順序;有一列,它只是錯誤)。而且你的代碼並沒有使用更現代的(自1992年以來)標準的SQL連接符號。但是,除了這些小問題之外,我相信這個問題的寫法是可行的。對於如何在答案中使用顯式連接編寫查詢,您有許多建議。 – 2012-01-09 20:20:40

回答

1

查詢中的GROUP BY必須去,你不必聚合任何東西。我更喜歡加入SQL92語法:

SELECT 
    Client.Fname, Client.Lname 
FROM 
    Staff 
INNER JOIN 
Class ON Staff.Sid = Class.Sid AND Staff.Fname = "Allen" AND Staff.Lname = "Moore" 
INNER JOIN 
Client ON Class.Cid = Cliente.Cid 
ORDER BY Cliente.lName ASC; 
+0

嚴格地說,GROUP BY是不必要的,但除了可能減慢查詢速度以外不會造成任何危害。但是,它與ORDER BY子句不同,並不保證數據將按排序順序顯示。 (如果有兩個不同的工作人員稱爲「Jane Doe」,這也可能很重要。) – 2012-01-09 20:14:36

+0

@jonathan leffler:在問題中使用的group by會造成很多傷害,因爲列列表不能包含沒有任何集合函數的列,它們不屬於group by子句的一部分。 – Mithrandir 2012-01-09 20:17:26

+0

啊 - 公平的評論。 MySQL會讓你擺脫它,但標準SQL(所有其他DBMS)不會。我的錯。 – 2012-01-09 20:23:30

2
select c.fname + ' ' + c.lname 
from Client c 
inner join Class cl 
on c.cid = cl.cid 
inner join Staff s 
on s.sid = cl.sid 
where s.fname = 'allen' 
and s.lname = 'moore' 
order by c.lname 
+1

如果您要欺騙並查找Allen Moore的員工ID,則無需加入Staff表。如果你用'WHERE s.Fname =「Allen」和S.Lname =「Moore」替換WHERE子句,那麼你就乾淨了,需要加入Staff。 – 2012-01-09 20:10:06

+0

@JonathanLeffler好點,固定。感謝您的更正。 – 2012-01-09 20:11:21

2

使用不同的別名,併爲更流行的慣例連接,但是您的查詢也應該工作。另外,ORDER BY升序是默認的,所以ASC是可選的...

SELECT CLNT.Fname, CLNT.Lname 
FROM Class AS CLS 
    INNER JOIN Client AS CLNT ON CLS.Cid = CLNT.Cid 
    INNER JOIN Staff AS S ON CLS.Sid = S.Sid 
WHERE S.Fname = 'Allen' 
     AND S.Lname = 'Moore' 
ORDER BY CLNT.Lname; 
+0

謝謝,現在我明白了。這與Mithrandir的回答基本相同。 – Ziai 2012-01-09 20:28:07

1

由於沒有其他表中的信息實際上正在使用,爲什麼要加入?

SELECT FName, LName 
FROM Client 
WHERE 
    Cid IN (
     SELECT Cid 
     FROM Class 
     WHERE Sid = (
      SELECT Sid FROM Staff WHERE FName = 'Allen' AND LName = 'Moore' 
     ) 
    ) 
ORDER BY LName ASC; 
+0

您的查詢與使用顯式連接編寫的查詢是同構的,優秀的優化程序會將它們視爲相同。你得到的肯定會奏效。 – 2012-01-09 20:22:25