无法从嵌套选择

时间:2017-10-21 06:12:20

标签: sql oracle join group-by

我有2张桌子

产品

PID  NAME                ORIGINAL_PRICE    DISCNT_RATE
---- -----------         --------------    -----------
p001 stapler                      9.99          .1
p002 TV                           249           .15
p003 camera                       148           .2

购买

  PUR# EID PID  CID         QTY PTIME     TOTAL_PRICE
------ --- ---- ---- ---------- --------- -----------
100001 e01 p002 c001          1 12-AUG-17      211.65
100002 e01 p003 c001          1 20-SEP-17       118.4
100003 e02 p004 c002          5 08-OCT-17        4.95
100005 e04 p007 c004          1 15-OCT-17       119.2
100006 e03 p008 c001          1 12-OCT-17       349.3

查找按总数量销售最多的每种产品的pid和名称。显示相应的总数量(标题:“销售总量”)。使用列格式将标题更改为“已售出总量”。

溶胶:

到目前为止,我所做的是

 SELECT Max("Total") AS "HS", pid 
 from (Select pid, sum(qty) as "Total"
 from purchases group by pid);

如果可以提供任何帮助,我无法按预期处理信息..

P.S:这不是作业

2 个答案:

答案 0 :(得分:0)

您可以使用Sum和group by获取总值,并使用TOP 1获得最大值

IN SQL SERVER

  select TOP 1 a.PID, sum(b.QTY) as "total quantity sold"
  FROM Products AS a
  INNER JOIN Purchases AS b on a.PID  = b.PID
  GROUP BY a.pID
  ORDER BY sum(b.QTY) DESC 

使用subselect中的max(你没有使用group by来获取一行)..会产生错误的结果,因为在大多数db中这是不允许的,或者可以显示随便获得的PID子选择的结果集..

如果你不想使用TOP(行数限制),你应该使用滤波器的最大值来确定subselect并获得正确的耦合PID,MAX tital

答案 1 :(得分:0)

对于销售量最大的产品的pid和名称:

从Oracle 12c开始,有一个fetch功能可以将输出限制为一行:

SELECT pu.pid, pr.name, sum(pu.qty) as "total quantity sold"
FROM PURCHASES pu
INNER JOIN PRODUCTS pr on pu.pid = pr.pid
GROUP BY pu.pid, pr.name
ORDER BY sum(pu.qty) DESC
FETCH FIRST 1 ROWS ONLY
;

对于支持row_number() over()的早期版本的Oracle(或具有相同功能支持的其他数据库):

SELECT pid, name, "total quantity sold"
FROM (
      SELECT pu.pid, pr.name, sum(pu.qty) as "total quantity sold"
           , ROW_NUMBER() OVER(ORDER BY sum(pu.qty) DESC) AS RN
      FROM PURCHASES pu
      INNER JOIN PRODUCTS pr on pu.pid = pr.pid
      GROUP BY pu.pid, pr.name
      ) 
WHERE RN = 1
;

但这两种方法都假设只有一行要报告。在更大的数据集中,可能有多于一行共享最高数量的总和。要返回所有此类行,请使用dense_rank() over()代替e,g,:

SELECT pid, name, "total quantity sold"
FROM (
      SELECT pu.pid, pr.name, sum(pu.qty) as "total quantity sold"
           , DENSE_RANK() OVER(ORDER BY sum(pu.qty) DESC) AS RNK
      FROM PURCHASES pu
      INNER JOIN PRODUCTS pr on pu.pid = pr.pid
      GROUP BY pu.pid, pr.name
      ) 
WHERE RNK = 1
;

请注意,在提供的示例中,products表中缺少PID p004 / p007 / p008。我认为这只是问题的遗漏。

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE PURCHASES
    (PURno int, EID varchar2(3), PID varchar2(4), CID varchar2(4), QTY int, PTIME timestamp, TOTAL_PRICE numeric)
;

INSERT ALL 
    INTO PURCHASES (PURno, EID, PID, CID, QTY, PTIME, TOTAL_PRICE)
         VALUES (100001, 'e01', 'p002', 'c001', 1, '12-Aug-2017 12:00:00 AM', 211.65)
    INTO PURCHASES (PURno, EID, PID, CID, QTY, PTIME, TOTAL_PRICE)
         VALUES (100002, 'e01', 'p003', 'c001', 1, '20-Sep-2017 12:00:00 AM', 118.4)
    INTO PURCHASES (PURno, EID, PID, CID, QTY, PTIME, TOTAL_PRICE)
         VALUES (100003, 'e02', 'p004', 'c002', 5, '08-Oct-2017 12:00:00 AM', 4.95)
    INTO PURCHASES (PURno, EID, PID, CID, QTY, PTIME, TOTAL_PRICE)
         VALUES (100005, 'e04', 'p007', 'c004', 1, '15-Oct-2017 12:00:00 AM', 119.2)
    INTO PURCHASES (PURno, EID, PID, CID, QTY, PTIME, TOTAL_PRICE)
         VALUES (100006, 'e03', 'p008', 'c001', 1, '12-Oct-2017 12:00:00 AM', 349.3)
SELECT * FROM dual
;
CREATE TABLE PRODUCTS
    (PID varchar2(5), NAME varchar2(70), ORIGINAL_PRICE int, DISCNT_RATE numeric)
;

INSERT ALL 
    INTO PRODUCTS (PID, NAME, ORIGINAL_PRICE, DISCNT_RATE)
         VALUES ('p001', 'stapler', 9.99, .1)
    INTO PRODUCTS (PID, NAME, ORIGINAL_PRICE, DISCNT_RATE)
         VALUES ('p002', 'TV', 249, .15)
    INTO PRODUCTS (PID, NAME, ORIGINAL_PRICE, DISCNT_RATE)
         VALUES ('p003', 'camera', 148, .2)
    INTO PRODUCTS (PID, NAME, ORIGINAL_PRICE, DISCNT_RATE)
         VALUES ('p004', 'p004 missing from sample', 0, 0)
    INTO PRODUCTS (PID, NAME, ORIGINAL_PRICE, DISCNT_RATE)
         VALUES ('p007', 'p007 missing from sample', 0, 0)
    INTO PRODUCTS (PID, NAME, ORIGINAL_PRICE, DISCNT_RATE)
         VALUES ('p008', 'p008 missing from sample', 0, 0)
SELECT * FROM dual
;

查询1

SELECT PID, NAME, "total quantity sold"
FROM (
      SELECT pu.pid, pr.name, sum(pu.qty) as "total quantity sold"
           , ROW_NUMBER() OVER(ORDER BY sum(pu.qty) DESC) AS RN
      FROM PURCHASES pu
      INNER JOIN PRODUCTS pr on pu.pid = pr.pid
      GROUP BY pu.pid, pr.name
      ) 
WHERE RN = 1
;

<强> Results

|  PID |                     NAME | total quantity sold |
|------|--------------------------|---------------------|
| p004 | p004 missing from sample |                   5 |

查询2

SELECT PID, NAME, "total quantity sold"
FROM (
      SELECT pu.pid, pr.name, sum(pu.qty) as "total quantity sold"
           , DENSE_RANK() OVER(ORDER BY sum(pu.qty) DESC) AS RNK
      FROM PURCHASES pu
      INNER JOIN PRODUCTS pr on pu.pid = pr.pid
      GROUP BY pu.pid, pr.name
      ) 
WHERE RNK = 1
;

<强> Results

|  PID |                     NAME | total quantity sold |
|------|--------------------------|---------------------|
| p004 | p004 missing from sample |                   5 |