我有两张桌子。
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;
它给我一个错误:single-row subquery returns more than one row
那么为什么会这样呢?我知道错误信息是什么。根据该文档,如果“外部查询必须使用其中一个关键字ANY,ALL,IN或NOT IN来指定要比较的值,则会触发此错误,因为子查询返回了多行。”不满意。但我无法理解为什么第一个代码符合条件,但第二个代码不符合。
DBMS:Oracle 11
答案 0 :(得分:1)
老兄你有重复的cust_id'1000000001'以及如何期待sql解决问题。你可以更详细地说明你的要求吗?可以看到他们中的许多人都不清楚你的问题。
如果存在多个(重复的)Cust_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;
如果我的建议错误,请纠正我,因为显然你应该能够理解这个问题。
答案 1 :(得分:0)
我真的不理解失败的陈述,甚至我也不知道为什么你需要一个order2表。 无论如何,我猜你想要计算每个客户ID的订单数量,如果是这样我认为没有必要进行子选择,你可以这样做
SELECT count(*) AS order_count, cust_id
FROM orders
GROUP BY cust_id
ORDER BY cust_id;
或者我错过了什么?
答案 2 :(得分:0)
帮助您了解差异:
因为您目前在Customers表上似乎没有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_id
值时,子查询返回太多行。
这就是为什么在构造此类查询时必须非常小心关系的基数。如果您犯了错误,查询可以成功运行多年,然后在返回额外行时突然中断。
答案 3 :(得分:0)
选择:
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;
因为你从Orders而不是从Custmer创建第二个表:
CREATE TABLE orders2 AS SELECT * FROM orders
并且该行重复使用cust_id` = 1000000001