代码正在运行但顶部(X)TOP PRICE没有相应提取。如何在我的代码中使用Ties?
一些顶部(x)被忽略。
这是我的表
STAFF_NUMBER STAFF_NAME PRICE
------------ ----------------------------------------- ----------
36 Helen Hilfg 330066
52 Octavia Chan 356885
36 Helen Hilfg 176088
4 Heidi Lee 231046
6 Jill Murphy 469844
32 Lily Roy 247549
58 John Roy 309299
这就是我得到的
SQL> SQL> SQL> exec p4(3)
PERSON# NAME
36 Helen Hilfg
52 Octavia Chan
4 Heidi Lee
这是我想要的
SQL> exec p4(3);
PERSON# NAME
--------------------
36 Helen Hilfg
6 Jill Murphy
52 Octavia Chan
这是我的程序
CREATE OR REPLACE PROCEDURE p3( X NUMBER )
AS
staff_number NUMBER ;
staff_name VARCHAR2(30) ;
CURSOR c1 IS
SELECT staff_number,
staff_name
FROM (SELECT P.peid staff_number,
P.firstname || ' ' || P.lastname staff_name ,
D.price PRICE
FROM Contact C,
Deal D,
Person P,
Staff S
WHERE S.peid = C.peid
AND C.pno = D.pno
AND P.peid = C.peid
AND (SYSDATE - D.day < 365))
WHERE ROWNUM <= X
GROUP BY staff_name , staff_number
ORDER BY SUM( price ) DESC ;
BEGIN
dbms_output.put_line( ' PERSON# ' ||' '||' NAME ' );
FOR R IN c1
LOOP
staff_number := R.staff_number ;
staff_name := R.staff_name ;
dbms_output.put_line( staff_number ||' '|| staff_name ) ;
END LOOP ;
END;
/
代码正在运行但顶部(X)TOP PRICE没有相应提取。如何在我的代码中使用Ties?
一些顶部(x)被忽略。
答案 0 :(得分:1)
当您说“没有输出”时,您是如何运行该程序的?你启用了dbms_output吗?例如,如果您在SQL * Plus中运行它,那么SET SERVEROUTPUT ON了吗?假设程序没有编译错误,你应该至少得到标题行。
查询本身是否在SQL * Plus中的过程之外运行?
答案 1 :(得分:1)
首先,如DCookie所建议,确保您已启用输出
set serveroutput on
如果您没有得到预期的结果,请尝试分解查询,直到找到数据丢失的位置,例如:如果去年没有交易,你不会得到任何回报,所以只选择一个符合标准的交易记录,然后检查其他表格是否匹配记录。同时确认每个表中都有数据,好像它们中的任何一个都是空的,结果集也是空的。
e.g。
select pno from deal where (sysdate - day) < 365;
(假设day是日期字段),然后从联系表
中选择此pnoselect peid from contact where pno=&pno;
从人员表中选择此peid,如果其中任何一个选项变为空,请检查该字段的示例值以确认ID号在表之间实际匹配,例如。
select count(*)
from deal d
where exists (select 1 from contact c where c.pno=d.pno)
select count(*)
from contact c
where exists (select 1 from person p where p.peid=c.peid)
您正在加入STAFF表,但STAFF和CONTACT都具有相同的peid字段,您不能从STAFF表中选择任何列,但您可以从person表中获取firstname,lastname和staff number。
人员表中是否还有其他可能是交易联系但不是员工的人(意味着加入员工是为了验证类型)?如果没有那么也许员工表在这里是多余的。
当你有一个复杂的查询(并且它们可能变得非常复杂,比如打印出A4的几页)时,你必须有一种方法将查询细分为更简单的查询,你可以验证每一步,这导致你到错误发生的地方。
希望有所帮助。
可能你应该使用分析函数,所以查询类似
select staff_number, staff_name from (
SELECT P.peid staff_number,
P.firstname || ' ' || P.lastname staff_name ,
D.price PRICE
RANK() OVER (ORDER BY d.price) AS position
FROM Contact C,
Deal D,
Person P,
Staff S
WHERE S.peid = C.peid
AND C.pno = D.pno
AND P.peid = C.peid
AND (SYSDATE - D.day < 365)
) where position < x
如果你想跳过几个有平局位置的人的位置,可以使用rank(),或者在有多个同一位置的记录的情况下使用dense_rank()。
只是看到你需要它来为同一个人总结交易所以可能更像这样(未经测试)
select staff_number, staff_name from (
SELECT P.peid staff_number,
P.firstname || ' ' || P.lastname staff_name ,
sum(D.price) PRICE
RANK() OVER (ORDER BY sum(d.price)) AS position
FROM Contact C,
Deal D,
Person P,
Staff S
WHERE S.peid = C.peid
AND C.pno = D.pno
AND P.peid = C.peid
AND (SYSDATE - D.day < 365)
group by p.peid, p.first_name|' '||p.lastname
) where position < x
肯定看一下分析函数,因为rownum只返回查询中的第一行,它不返回完整的结果集,然后给你前N条记录。您可能需要使用分区子句但尝试一下并在此处查看排名示例。
答案 2 :(得分:1)
请查看您的查询并尝试了解它正在做什么。
您有一个内部查询,可以过滤某些条件。您还没有向我们提供数据,因此我们无法预测结果会是什么样子。让我们假设它返回你认为它将要发生的记录。
然后在您的外部查询中,您有一个WHERE子句,它在ROWNUM <= X
上进行过滤。这意味着查询将返回三行,基本上是随机的,然后将根据SUM(PRICE)
对其进行分组和排序。
这显然不是你所期待的。但那是因为您不了解ROWNUM的工作原理。它很容易修复:您只需要将ROWNUM过滤器应用于分组和排序的结果。像这样:
SELECT * FROM (
SELECT staff_number,
staff_name
FROM (SELECT P.peid staff_number,
P.firstname || ' ' || P.lastname staff_name ,
D.price PRICE
FROM Contact C,
Deal D,
Person P,
Staff S
WHERE S.peid = C.peid
AND C.pno = D.pno
AND P.peid = C.peid
AND (SYSDATE - D.day < 365)
)
GROUP BY staff_name , staff_number
ORDER BY SUM( price ) DESC
)
WHERE ROWNUM <= X
;