2012-01-09 95 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