&引用;单行子查询返回多行;SQL错误

&引用;单行子查询返回多行;SQL错误,sql,oracle,Sql,Oracle,我有两张桌子 CREATE TABLE Customers ( cust_id char(10) NOT NULL , cust_name char(50) NOT NULL , cust_address char(50) NULL , cust_city char(50) NULL , cust_state char(5) NULL , cust_zip char(10) NULL , cust_country cha

我有两张桌子

CREATE TABLE Customers
(
  cust_id      char(10)  NOT NULL ,
  cust_name    char(50)  NOT NULL ,
  cust_address char(50)  NULL ,
  cust_city    char(50)  NULL ,
  cust_state   char(5)   NULL ,
  cust_zip     char(10)  NULL ,
  cust_country char(50)  NULL ,
  cust_contact char(50)  NULL ,
  cust_email   char(255) NULL 
);
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000001', 'Village Toys', '200 Maple Lane', 'Detroit', 'MI', '44444', 'USA', 'John Smith', 'sales@villagetoys.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000002', 'Kids Place', '333 South Lake Drive', 'Columbus', 'OH', '43333', 'USA', 'Michelle Green');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000003', 'Fun4All', '1 Sunny Place', 'Muncie', 'IN', '42222', 'USA', 'Jim Jones', 'jjones@fun4all.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000004', 'Fun4All', '829 Riverside Drive', 'Phoenix', 'AZ', '88888', 'USA', 'Denise L. Stephens', 'dstephens@fun4all.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000005', 'The Toy Store', '4545 53rd Street', 'Chicago', 'IL', '54545', 'USA', 'Kim Howard');

CREATE TABLE Orders
(
  order_num  int      NOT NULL ,
  order_date date     NOT NULL ,
  cust_id    char(10) NOT NULL 
);
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20005, TO_DATE('2012-05-01', 'yyyy-mm-dd'), '1000000001');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20006, TO_DATE('2012-01-12', 'yyyy-mm-dd'), '1000000003');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20007, TO_DATE('2012-01-30', 'yyyy-mm-dd'), '1000000004');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20008, TO_DATE('2012-02-03', 'yyyy-mm-dd'), '1000000005');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20009, TO_DATE('2012-02-08', 'yyyy-mm-dd'), '1000000001');
有趣的是,如果我跑步:

SELECT count(*) AS order_count,
  (SELECT cust_name
   FROM customers
   WHERE customers.cust_id=orders.cust_id) AS cust_name,
   cust_id
FROM orders
GROUP BY cust_id
ORDER BY cust_id;
没有错误

但如果我创建一个新表并运行类似的代码:

CREATE TABLE orders2 AS SELECT * FROM orders
SELECT count(*) AS order_count,
  (SELECT cust_id
   FROM orders2
   WHERE orders2.cust_id=orders.cust_id) AS cust_id2,
   cust_id
FROM orders
GROUP BY cust_id
ORDER BY cust_id;
它给了我一个错误:
单行子查询返回多行

那么为什么会发生这种情况呢?我知道错误信息是什么。根据文档,如果“外部查询必须使用关键字ANY、ALL、IN或NOT IN中的一个来指定要比较的值,因为子查询返回了多行”,则会触发此错误。但我不明白为何第一个守则是符合资格的,而第二个则不符合资格


DBMS:Oracle11

我真的不理解失败的语句,更不明白为什么需要orders2表。 不管怎么说,我猜你们想要每个客户id的订单数量,若我认为并没有必要再选择,你们可以这样做

SELECT count(*) AS order_count, cust_id
FROM orders
GROUP BY cust_id
ORDER BY cust_id;

还是我遗漏了什么?

为了帮助您理解差异:

因为您目前似乎没有客户表上的PK,请执行以下操作:

INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000005', 'DUPLICATE CUST_ID', '4545 53rd Street', 'Chicago', 'IL', '54545', 'USA', 'Kim Howard');
  • 然后再次尝试运行第一个查询。您应该注意到,它现在也会失败,并出现相同的错误
  • 相反,如果只对第二个查询执行解析检查而不运行它:您不会得到错误,因为它在语法上是正确的
那么为什么会发生这种情况呢

您的代码类似,但数据不同。该错误由执行查询时检测到的数据问题触发。仅编译查询时无法检测到此错误

但我不明白为何第一个守则是符合资格的,而第二个则不符合资格

两个查询中的代码均有效。只是在对某些
orders.cust\u id
值执行子查询时返回的行太多

这就是为什么在构造此类查询时必须非常小心关系的基数。如果出错,查询可以成功运行数年,然后在返回额外行时突然中断。

选择:

SELECT count(*) AS order_count,
  (SELECT cust_id
   FROM orders2
   WHERE orders2.cust_id=orders.cust_id) AS cust_id2,
   cust_id
FROM orders
GROUP BY cust_id
ORDER BY cust_id;
与选择不同:

    SELECT count(*) AS order_count,
  (SELECT cust_name
   FROM customers
   WHERE customers.cust_id=orders.cust_id) AS cust_name,
   cust_id
FROM orders
GROUP BY cust_id
ORDER BY cust_id;
因为您是根据订单而不是客户创建第二个表:

CREATE TABLE orders2 AS SELECT * FROM orders

cupplicate行的cust\u id`=1000000001

Dude您有重复的cust\u id'1000000001'以及如何期望sql工作。你能更详细地说明你的要求吗。可以看出他们中的许多人对你的问题并不清楚

这是毫无根据的,因为如果存在多个(重复的)客户id,那么Oracle肯定会通过您发送此错误消息

使用Distinct已经解决了查询,我没有收到更多的错误消息

SELECT count(*) AS order_count,
  (SELECT distinct cust_id
FROM orders2
WHERE orders2.cust_id=orders.cust_id) AS cust_id2,
cust_id
FROM orders
GROUP BY cust_id
ORDER BY cust_id;

如果我的建议是错误的,请纠正我,因为很明显你应该能够理解这个问题

同一
客户id的
订单2中有多行
无法理解您的期望。首先使用表
customers
,然后使用
orders
创建其他表,而不是从
customers
复制,然后对该表使用query并表示“相似”?该错误显然是由于表
orders
中重复的cust_id
1000000001
及其副本表
orders2
第二次查询在其子查询中使用了
orders
的副本。您的第一次使用
客户
。您的代码可能类似,但您的数据完全不同。