这些查询是否正确?

时间:2013-09-18 11:02:28

标签: mysql sql foreign-keys subquery

我有以下表格:

商城:

+-----------+----------------------+------+-----+---------+----------------+
| Field     | Type                 | Null | Key | Default | Extra          |
+-----------+----------------------+------+-----+---------+----------------+
| MallID    | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
| Name      | varchar(45)          | NO   |     | NULL    |                |
+-----------+----------------------+------+-----+---------+----------------+

商品

+------------+----------------------+------+-----+---------+----------------+
| Field      | Type                 | Null | Key | Default | Extra          |
+------------+----------------------+------+-----+---------+----------------+
| StoreID    | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
| MallID     | smallint(5) unsigned | NO   | MUL | NULL    |                |
| Name       | varchar(45)          | NO   |     | NULL    |                |
| Revenue    | int(10)              | NO   |     | NULL    |                |
+------------+----------------------+------+-----+---------+----------------+

客户:

+------------+----------------------+------+-----+---------+----------------+
| Field      | Type                 | Null | Key | Default | Extra          |
+------------+----------------------+------+-----+---------+----------------+
| CustomerID | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
| StoreID    | smallint(5) unsigned | NO   | MUL | NULL    |                |
| Name       | varchar(45)          | NO   |     | NULL    |                |
| Age        | smallint(3)          | NO   |     | NULL    |                |
+------------+----------------------+------+-----+---------+----------------+

Store.MallIDMall.MallID的外键,Customer.StoreIDStore.StoreID的外键

1 - 我想选择商店总收入超过100000的所有商城。

select * from Mall where 100000 < ( select sum(Revenue) from Store where Mall.MallID = Store.MallID);

2 - 我想选择没有任何顾客的商城名称。

select Name from Mall where 0 = ( select count(*) from Customer, Store where Mall.MallID = Store.MallID and Store.StoreID = Customer.StoreID);

这些查询是否正确?

4 个答案:

答案 0 :(得分:2)

他们是正确的,但有更好的(恕我直言)方式来写它们:

SELECT m.*
FROM Mall m
JOIN (SELECT MallID, SUM(Revenue) totalRev
      FROM Store
      GROUP BY MallID
      HAVING totalRev > 100000) s
ON s.MallID = m.MallID

SELECT m.Name
FROM Mall m
LEFT JOIN (SELECT DISTINCT s.MallID
           FROM Customer c
           JOIN Store s
           ON c.StoreID = s.StoreID) s
ON m.MallID = s.MallID
WHERE s.MallID IS NULL

答案 1 :(得分:2)

您的查询符合您的期望。我会使用ANSI标准join语法编写第二个,并鼓励您使用缩写作为表别名:

select Name
from Mall m
where 0 = (select count(*)
           from Customer c join
                Store s 
                on Mall.MallID = Store.MallID 
           where Store.StoreID = Customer.StoreID
          );

另一种方法是将所有这些作为单个连接和聚合来完成:

select m.Name
from Mall m left outer join
     Store s
     on s.MallID = m.MallID left outer join
     Customer c
     on s.StoredId = c.StoreId
group by m.Name
having count(c.CustomerId) = 0;

在MySQL中,我不鼓励你在子查询中进行聚合,然后加入它。虽然是一个非常好的SQL解决方案,MySQL实际上为这些子查询创建派生表,这有时会对性能产生负面影响。 / p>

答案 2 :(得分:2)

他们是正确的,我已经在这里为你检查过了:

http://sqlfiddle.com/#!2/6a496/12

你可以使用一些建议的sql命令,也可以保留你的(编写查询的方法很多!)

1

SELECT * 
FROM Mall 
where MallID in (
      SELECT MallID
      FROM Store
      GROUP BY MallID
      HAVING SUM(Revenue) > 100000)

2

SELECT Name
FROM Mall
WHERE (SELECT count(*) 
       FROM Customer, Store 
       WHERE Mall.MallID = Store.MallID and Store.StoreID = Customer.StoreID
      )=0;

答案 3 :(得分:0)

我建议在查询2中使用外连接,因为可能有一个没有商店的空商城,因此没有客户。

select Name from Mall where 0 = ( select count(*) from Customer, Store where Mall.MallID(+) = Store.MallID and Store.StoreID = Customer.StoreID);

由于 Niraj Rathi