获取已通过销售员工下订单的客户城市的名称

时间:2018-04-16 06:35:02

标签: sql mariadb

对于我的CIS类,我有SQL项目,我仍然是SQL的新手,并试图学习它。任何帮助将不胜感激。

查询:获取已通过销售图书" Quickbooks for Business"的员工下订单的客户的城市名称。必需:您必须使用子选择完成此查询。

这是我试过的并给我一个错误:

IProduct

我得到的错误是:#1064 - 您的SQL语法出错;查看与您的MariaDB服务器版本对应的手册,以获得在''附近使用的正确语法。在第11行

表:Table

数据库代码:

SELECT city
FROM zipcode, book, customer, orderline
where city in (SELECT city FROM zipcode WHERE
zip in (SELECT zip 
        FROM customer 
        WHERE cno IN
             (SELECT cno 
              FROM salesorder 
              WHERE ono IN (SELECT ono 
                            FROM orderline 
                            WHERE bno IN (SELECT bno 
                                          FROM book 
                                          WHERE bname ('Quickbooks for Business') )
                            )
              )
        )

示例数据:

create table zipcode (
  zip   integer(5) primary key,
  city  varchar(30),
  State varchar(20));

create table employee (
  eno       varchar(10) primary key,
  ename     varchar(30),
  zip       integer(5) references zipcode(zip),
  hire_date date);

create table book (
  bno       integer(5) primary key,
  bname     varchar(30),
  qoh       integer(5) not null,
  price     dec(6,2) not null);

create table customer (
  cno       integer(5) primary key,
  cname     varchar(30),
  street    varchar(30),
  zip       integer(5)  references zipcode(zip),
  phone     char(12));

create table salesOrder (
  ono       integer(5)  primary key,
  cno       integer(5)  references customer(cno),
  eno       varchar(10)  references employees(Eno),
  received  date,
  shipped   date
);

create table orderLine (
  ono       integer(5)  references salesOrder(ono),
  bno       integer(5)  references book(bno),
  quantity  integer(10) not null,
  primary key (ono, bno));

3 个答案:

答案 0 :(得分:2)

您应该使用JOINS代替Sub-Queries

SELECT DISTINCT Z.city
FROM zipcode Z
JOIN customer C ON C.zip = Z.zip
JOIN salesOrder S ON S.cno = C.cno
JOIN orderLine O ON O.ono = S.ono
JOIN book B ON B.bno = O.bno
WHERE B.bname = 'Quickbooks for Business'

答案 1 :(得分:0)

试试这个。虽然使用joins可以做得更好,但这是你应该通过子查询做的。

select city from zipcode 
where zip in
(select zip from customer 
    where cno in(
        select cno from salesOrder 
        where ono in (
            select ono from orderLine 
            where bno in (
                SELECT bno FROM book 
                where bname = 'Quickbooks for Business'
                        )
                    )
                )
)

答案 2 :(得分:0)

这是一个足够复杂的查询,我可以使用我称之为“测试驱动的查询设计”来解决它。或TDQD。这里有两个查询序列导致相同的合理答案 - 问题中未给出预期输出,这使得很难确定查询是否已被准确分析。

要求表述为:

  • 查询:获取已通过销售该书的员工下订单的客户的城市名称" Quickbooks for Business"。
  • 必填:您必须使用子选择完成此查询。

通过子选择'可以解释'要求表示至少一个子查询'或者只使用子查询'。这个答案分为两部分 - 第一部分假设单个子查询就足够了,第二部分假设只能使用子查询。

我认为TDQD是一种很好的学习方法,可以学习如何通过大量的小查询构建大型查询(因为您测试了小型查询)。

一个子查询就足够了

TDQD第A1步 - 出售该书的员工' Businessbooks for Business'

这是一个相当大的第一步;如果您不熟悉编写查询,可以将其细分为较小的查询以构建员工编号的输出列表。

SELECT e.eno
  FROM employee AS e
  JOIN salesorder AS o ON o.eno = e.eno
  JOIN orderline AS l ON o.ono = l.ono
  JOIN book AS b ON l.bno = b.bno
 WHERE b.bname = 'Quickbooks for Business';

输出:

P0239401
P0239402

简化:查询不需要包含employee表;员工编号位于salesOrder表中:

SELECT o.eno
  FROM salesorder AS o
  JOIN orderline AS l ON o.ono = l.ono
  JOIN book AS b ON l.bno = b.bno
 WHERE b.bname = 'Quickbooks for Business';

这给出了相同的结果。可以通过所有查询传播更改。请注意,答案的第二部分('所有子查询'变体)也不会从employee表中进行选择。这种不对称应该让我早点离开,但我没有发现它。而且如果我用较小的步骤在TDQD序列中建立第一步,那么我也不会在这里犯错误。

TDQD步骤A2 - 从员工列表中下订单的客户

SELECT c.cno
  FROM customer AS c
  JOIN salesorder AS o ON c.cno = o.cno
 WHERE o.eno IN
       (SELECT e.eno
          FROM employee AS e
          JOIN salesorder AS o ON o.eno = e.eno
          JOIN orderline AS l ON o.ono = l.ono
          JOIN book AS b ON l.bno = b.bno
         WHERE b.bname = 'Quickbooks for Business'
       );

这为您提供了强制性的子查询。

输出:

23513
23511
23513
23511
23512
23513

这是一个中间结果;没有必要删除重复项或订购此结果。

简化:

SELECT c.cno
  FROM customer AS c
  JOIN salesorder AS o ON c.cno = o.cno
 WHERE o.eno IN
       (SELECT o.eno
          FROM salesorder AS o
          JOIN orderline AS l ON o.ono = l.ono
          JOIN book AS b ON l.bno = b.bno
         WHERE b.bname = 'Quickbooks for Business'
       );

TDQD步骤A3 - 从员工名单下订单的客户城市

SELECT DISTINCT z.city
  FROM customer   AS c
  JOIN salesorder AS o ON c.cno = o.cno
  JOIN zipcode    AS z ON z.zip = c.zip
 WHERE o.eno IN
       (SELECT e.eno
          FROM employee   AS e
          JOIN salesorder AS o ON o.eno = e.eno
          JOIN orderline  AS l ON o.ono = l.ono
          JOIN book       AS b ON l.bno = b.bno
         WHERE b.bname = 'Quickbooks for Business'
       )
 ORDER BY z.city;

输出:

Bellingham
San Jose

简化:

SELECT DISTINCT z.city
  FROM customer AS c
  JOIN salesorder AS o ON c.cno = o.cno
  JOIN zipcode AS z ON z.zip = c.zip
 WHERE o.eno IN
       (SELECT o.eno
          FROM salesorder AS o
          JOIN orderline AS l ON o.ono = l.ono
          JOIN book AS b ON l.bno = b.bno
         WHERE b.bname = 'Quickbooks for Business'
       )
 ORDER BY z.city;

TDQD步骤A4 - 不要使用子查询

作业需要子查询,但现实世界并不需要。但是,SalesOrder表必须在查询中计算两次,所以 它被别名o1o2

- TDQD第4步 - 不要使用子查询

SELECT DISTINCT z.city
  FROM customer   AS c
  JOIN salesorder AS o1 ON c.cno  = o1.cno
  JOIN zipcode    AS z  ON c.zip  = z.zip
  JOIN employee   AS e  ON o1.eno = e.eno
  JOIN salesorder AS o2 ON o2.eno = e.eno
  JOIN orderline  AS l  ON o2.ono = l.ono
  JOIN book       AS b  ON l.bno  = b.bno
 WHERE b.bname = 'Quickbooks for Business'
 ORDER BY z.city;

输出:

Bellingham
San Jose

简化:

SELECT DISTINCT z.city
  FROM customer   AS c
  JOIN salesorder AS o1 ON c.cno  = o1.cno
  JOIN zipcode    AS z  ON z.zip  = c.zip
  JOIN salesorder AS o2 ON o2.eno = o1.eno
  JOIN orderline  AS l  ON o2.ono = l.ono
  JOIN book       AS b  ON l.bno  = b.bno
 WHERE b.bname = 'Quickbooks for Business'
 ORDER BY z.city;

只能使用子查询

如果单个子查询足够的假设是错误的,实际上只能使用子查询,那么接下来会有一个替代的TDQD序列。

TDQD步骤B1 - 商业快速书的书号' (Q FB个)

SELECT b.bno
  FROM book AS b
 WHERE b.bname = 'Quickbooks for Business';

输出:

10605

TDQD步骤B2 - 订单的订单号,包括QfB

SELECT l.ono
  FROM orderline AS l
 WHERE l.bno IN
       (SELECT b.bno
          FROM book AS b
         WHERE b.bname = 'Quickbooks for Business'
       );

输出:

1021
1022

TDQD步骤B3 - 订单的员工编号,包括QfB

SELECT DISTINCT o1.eno
  FROM salesorder AS o1
 WHERE o1.ono IN
       (SELECT l.ono
          FROM orderline AS l
         WHERE l.bno IN
               (SELECT b.bno
                  FROM book AS b
                 WHERE b.bname = 'Quickbooks for Business'
               )
       );

输出:

P0239401
P0239402

TDQD步骤B4 - 通过列表中的员工下订单的客户编号

SELECT DISTINCT o2.cno
  FROM salesorder AS o2
 WHERE o2.eno IN
       (SELECT o1.eno
          FROM salesorder AS o1
         WHERE o1.ono IN
               (SELECT l.ono
                  FROM orderline AS l
                 WHERE l.bno IN
                       (SELECT b.bno
                          FROM book AS b
                         WHERE b.bname = 'Quickbooks for Business'
                       )
               )
       );

输出:

23511
23512
23513

TDQD步骤B5 - 通过列表

中的员工下订单的客户的邮政编码
SELECT DISTINCT c.zip
  FROM customer AS c
 WHERE c.cno IN
       (SELECT o2.cno
          FROM salesorder AS o2
         WHERE o2.eno IN
               (SELECT o1.eno
                  FROM salesorder AS o1
                 WHERE o1.ono IN
                       (SELECT l.ono
                          FROM orderline AS l
                         WHERE l.bno IN
                               (SELECT b.bno
                                  FROM book AS b
                                 WHERE b.bname = 'Quickbooks for Business'
                               )
                       )
               )
       );

输出:

95124
98225

TDQD步骤B6 - 通过列表中的员工下订单的客户城市

SELECT DISTINCT z.city
  FROM zipcode AS z
 WHERE z.zip IN
       (SELECT DISTINCT c.zip
          FROM customer AS c
         WHERE c.cno IN
               (SELECT o2.cno
                  FROM salesorder AS o2
                 WHERE o2.eno IN
                       (SELECT o1.eno
                          FROM salesorder AS o1
                         WHERE o1.ono IN
                               (SELECT l.ono
                                  FROM orderline AS l
                                 WHERE l.bno IN
                                       (SELECT b.bno
                                          FROM book AS b
                                         WHERE b.bname = 'Quickbooks for Business'
                                       )
                               )
                       )
               )
       );

输出:

Bellingham
San Jose

幸运的是,为最终查询生成了相同的输出。 这使我们更加确信查询是等效的。