Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql TOP 1或LIMIT 1在相关子查询中不起作用-SPS 11_Sql_Hana - Fatal编程技术网

Sql TOP 1或LIMIT 1在相关子查询中不起作用-SPS 11

Sql TOP 1或LIMIT 1在相关子查询中不起作用-SPS 11,sql,hana,Sql,Hana,我正在尝试进行一个查询,以使用前一记录中的非零值填充产品的零价格。我试图编写一个简单的相关子查询,但它不起作用 var_1 = select * from "XYZ"."PRD_TEST" where price <> 0 order by period desc; var_out = select a.product,a.period, ( select price from :var_1 b where a.product = b.product and a.period &g

我正在尝试进行一个查询,以使用前一记录中的非零值填充产品的零价格。我试图编写一个简单的相关子查询,但它不起作用

var_1 = select * from "XYZ"."PRD_TEST" where price <> 0 order by period desc;

var_out = select a.product,a.period, ( select price from :var_1 b where a.product = b.product and a.period > b.period and b.period <> 0 limit 1 ) as price from "XYZ"."PRD_TEST" a;

PRODUCT PERIOD PRICE
A 1 100
A 2 0 - to be filled with 100
A 3 0 - to be filled with 100
A 4 5
A 5 0 - to be filled with 5
var_1=从“XYZ”中选择*,“PRD_测试”,其中价格为0,按时段描述订购;
var_out=选择a.product,a.period(从:var_1 b中选择价格,其中a.product=b.product和a.period>b.period和b.period 0限制1)作为“XYZ”中的价格。“PRD_测试”a;
产品周期价格
A 1100
A 20-用100填充
A 30-用100填充
A 45
A 5 0-用5填充
我试图用标量函数替换子查询,但它不将表作为参数

我尝试使用左外连接和Row_number实现输出,但它太昂贵,而且运行时间很长


我正在寻找一个最佳选项,以便在子查询中仅获取1条记录,就像TOP 1一样。

您可以使用这样的标量子查询(遗憾的是,选择…限制1在HANA中不被视为标量):

开始
var_1=select*from((从sys.dummy中选择“A”产品、“1”期间、“100”价格)
联合(从sys.dummy中选择“A”产品、“2”期间、“0”价格)
联合(从sys.dummy中选择“A”产品、“3”期间、“0”价格)
联合(从sys.dummy中选择“A”产品、“4”期间、“5”价格)
联合(从sys.dummy中选择“A”产品、“5”期间、“0”价格))按期间描述订购;
var_out=(选择一个产品,
a、 期间,,
(选择最大值(价格)
发件人:var_1 b
其中a.product=b.product
a.周期>b.周期
和b.0
和b.period=(从:var_1 c中选择max(period)
其中a.product=c.product
a.周期>c.周期
和c.0
价格为0
))作为价格
from:var_1 a,其中价格='0')
联合(从变量1中选择产品、期间、价格,其中价格为“0”);
选择*来源:按产品、期间分类的var_出库单;
结束
在sps12上测试

评论后添加。 你为什么不试试呢?这很简单。 因为好奇,我在我的HCP试用版上试用了它,在百万行上大约需要1秒钟。我包含了一个ifnull,以避免在早期没有价格的情况下使用null值的行

以下是编码:

drop table var_1;
create column table var_1 as 
(
    select 
      cast ( 'Prod' || prd.GENERATED_PERIOD_START as nvarchar(20) ) product, 
      cast ( per.GENERATED_PERIOD_START as decimal(2)) period,
      cast ( case when rand() < '0.5' then rand() * '100' else '0' end 
             as decimal(5,2)) as price -- ~50% of price is 0
      from series_generate_integer(1,0,1000000/13) as prd,  --~1Mio records
           series_generate_integer(1,0,13) as per --12 periods + period 0 
);
merge delta of var_1;
select * from var_1
 order by product, period 
 limit 100;
do begin sequential execution -- don't let parallel execution influence the runtime-measurement
declare start_timestamp timestamp;
start_timestamp = current_timestamp;
var_out = ( select a.product,
             a.period, 
            ifnull ((select max(price) 
              from var_1 b 
              where a.product = b.product 
              and a.period > b.period 
              and b.period <> 0 
              and b.period = ( select max(period) from var_1 c 
                               where a.product = c.product
                                 AND a.period > c.period
                                 and c.period <> 0
                                 and c.price <> 0
              )),'0.0') as price 
              from var_1 a where price = '0' )
union (select product, period, price from var_1 where price <> '0' );

select nano100_between(:start_timestamp, (select current_timestamp from dummy) )/10000 as runtime_millisec from dummy;

select * from :var_out
 order by product, period 
 limit 100;
end
drop table var_1;
将列表var_1创建为
(
挑选
铸造('Prod'| | prd.GENERATED|u PERIOD|u START as nvarchar(20))产品,
强制转换(每生成的\u周期\u开始为十进制(2))周期,
强制转换(当rand()小于“0.5”时,则为rand()*“100”,否则为“0”结束
以十进制(5,2))表示价格--50%的价格为0
从系列_生成_整数(1,01000000/13)作为prd,--1Mio记录
序列_根据--12个周期+周期0生成_整数(1,0,13)
);
var_1的合并增量;
从变量1中选择*
按产品、期间排序的订单
上限为100;
开始顺序执行——不要让并行执行影响运行时度量
声明开始时间戳时间戳;
开始时间戳=当前时间戳;
var_out=(选择一个产品,
a、 期间,,
ifnull((选择最大值(价格)
来自var_1 b
其中a.product=b.product
a.周期>b.周期
和b.0
和b.period=(从var_1 c中选择max(period)
其中a.product=c.product
a.周期>c.周期
和c.0
价格为0
))“0.0”)作为价格
来自var_1 a,其中价格='0')
联合(从变量1中选择产品、期间、价格,其中价格为“0”);
从(:start_timestamp,(从dummy选择current_timestamp))/10000之间选择nano100_,作为从dummy选择runtime_毫秒;
选择*from:var\u out
按产品、期间排序的订单
上限为100;
结束

非常感谢您的帮助,克里斯!!只是想知道如果VAR_1 temp表中的条目超过一百万,性能会如何?嵌套的子查询(如果我称之为错误的,请纠正我)会产生性能问题吗?@gokul:为什么不直接衡量性能的好坏。?在您的用例中,什么是好的性能?只是出于好奇,我加入了生成测试数据和测量执行时间的编码。HCP试验中每百万记录1秒并没有那么糟糕,对吗?查看解释计划或计划向导中的语句也会很有趣。也许你可以这样做,为这个问题增加一些价值。而且,也许其中一位专家会用窗口功能或其他花哨的东西想出一些更快的解决方案……嗨,克里斯,我正在进行更改,我一定会更新查询的性能,再次感谢你的努力。@gokul:如果答案是对的,并且对你有帮助,那么投票或/或接受我的答案就好了。嗨,克里斯,我投了赞成票并接受了答案。非常感谢你的帮助。
drop table var_1;
create column table var_1 as 
(
    select 
      cast ( 'Prod' || prd.GENERATED_PERIOD_START as nvarchar(20) ) product, 
      cast ( per.GENERATED_PERIOD_START as decimal(2)) period,
      cast ( case when rand() < '0.5' then rand() * '100' else '0' end 
             as decimal(5,2)) as price -- ~50% of price is 0
      from series_generate_integer(1,0,1000000/13) as prd,  --~1Mio records
           series_generate_integer(1,0,13) as per --12 periods + period 0 
);
merge delta of var_1;
select * from var_1
 order by product, period 
 limit 100;
do begin sequential execution -- don't let parallel execution influence the runtime-measurement
declare start_timestamp timestamp;
start_timestamp = current_timestamp;
var_out = ( select a.product,
             a.period, 
            ifnull ((select max(price) 
              from var_1 b 
              where a.product = b.product 
              and a.period > b.period 
              and b.period <> 0 
              and b.period = ( select max(period) from var_1 c 
                               where a.product = c.product
                                 AND a.period > c.period
                                 and c.period <> 0
                                 and c.price <> 0
              )),'0.0') as price 
              from var_1 a where price = '0' )
union (select product, period, price from var_1 where price <> '0' );

select nano100_between(:start_timestamp, (select current_timestamp from dummy) )/10000 as runtime_millisec from dummy;

select * from :var_out
 order by product, period 
 limit 100;
end