标题:如何利用sql实现EXCEL中lookup函数的功能
只看楼主
colorto
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2014-8-1
结帖率:25%
已结贴  问题点数:10 回复次数:14 
如何利用sql实现EXCEL中lookup函数的功能
在excel中进行数值分析时候经常采用lookup进行查询匹配,例如hdm表中第一列桩号(1,2,3,4,5,6)第二列kr(A,B,C,D,E,F)
 则cal2表中计算2.2对应的值时,应返回小于2.2的最大值,即2对应的列值为B,请问在sql中如何实现,我写了一个sql语句,但是运行非常慢
在access中
DoCmd.RunSQL "update cal2 as t1 left join hdm as t2 on t1.起点>=t2.桩号set t1.K=t2.kr"         ‘运行了12秒
DoCmd.RunSQL "update cal2 as t1 left join hdm as t2 on t1.起点 =t2.桩号set t1.K=t2.kr"         ’运行了0.48秒

补充说明
左侧为A表 右侧为B表,已知起点,求K,在excel中用=LOOKUP(I9,$F$9:$F$15,$G$9:$G$15)函数 一拖就出来了,可是在access中却需要12秒



补充说明2:
现在A表中已知n(6000)个点的坐标,在B表中已知m(4000)多个点的X坐标,要求其Y坐标,根据线性代数y=kx+b,我在A表中已经计算了每个点对应的K和B,现在在b表中计算已知点的斜率,即线性插入值的y坐标

你也可以理解为根据用电量查询用电的单价,单价是阶梯单价

[此贴子已经被作者于2016-7-10 07:53编辑过]

搜索更多相关主题的帖子: sql语句 access update excel 最大值 
2016-07-09 19:42
mywisdom88
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:10 
多少条记录,这么慢
2016-07-09 22:32
colorto
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2014-8-1
得分:0 
A表6000条 B表600条 笛卡尔积估计3600000条了 这估计是慢的原因 归根到底还是方法不对

我觉得这个应该是一个很简单的sql语句,比方说根据基本工资查所得税的税率;根据用电量采用阶梯单价;线性插值都用得到,被这个知识点卡了个把月了,

[此贴子已经被作者于2016-7-9 22:59编辑过]

2016-07-09 22:50
mywisdom88
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
DoCmd.RunSQL "update cal2 as t1 left join hdm as t2 on t1.起点 =t2.桩号set t1.K=t2.kr"
看了半天,才知道,语法怎么和SQL2000不同的。。
我记得,SQL2000好像是这样写的。

create table #test1(id int,name varchar(10))
insert into #test1(id,name) values(1,'a1')
insert into #test1(id,name) values(2,'a2')
insert into #test1(id,name) values(3,'a3')
insert into #test1(id,name) values(4,'a4')
insert into #test1(id,name) values(5,'a5')
insert into #test1(id,name) values(6,'a6')


create table #test2(id int,name varchar(10))
insert into #test2(id,name) values(1,'')
insert into #test2(id,name) values(2,'')
insert into #test2(id,name) values(3,'')
insert into #test2(id,name) values(4,'')
insert into #test2(id,name) values(5,'')
insert into #test2(id,name) values(6,'')

select * from #test1
select * from #test2
update #test2 set name=t1.name from #test1 as t1 where #test2.id=t1.id
select * from #test2
这样的语句,应该不慢啊
2016-07-09 23:59
colorto
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2014-8-1
得分:0 
你写的这个是精确匹配 和我写的第二句是一样的,这个速度不慢,我的意思是 模糊匹配,打个比方 如果查询3.3对应的值 在test1表中是查不到的,这时候就需要模糊匹配了,在test1表的name列中首先找到小于3.3的最大值,即3,再找到3对应的值A3,也就是说3.3对应的值是A3,同理4.4对应A4,5.1~5.9对应A5。sql语句中的on后面的条件不能是等于
2016-07-10 07:37
mywisdom88
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
--表 #test1 对应你表 cal2
--create table #test1(桩号 int,kr varchar(10))
--insert into #test1(桩号,kr) values(1,'a1')
--insert into #test1(桩号,kr) values(2,'a2')
--insert into #test1(桩号,kr) values(3,'a3')
--insert into #test1(桩号,kr) values(4,'a4')
--insert into #test1(桩号,kr) values(5,'a5')
--insert into #test1(桩号,kr) values(6,'a6')

--表 #test2 对应你表 hdm,有多个数据,如 1.1,1.2
--create table #test2(起点 numeric(10,1),kn varchar(10))
--insert into #test2(起点,kn) values(1.1,'a1.1')
--insert into #test2(起点,kn) values(1.2,'a1.2')
--insert into #test2(起点,kn) values(2.2,'a2.2')
--insert into #test2(起点,kn) values(3.1,'a3.1')
--insert into #test2(起点,kn) values(4.5,'a4.5')
--insert into #test2(起点,kn) values(5.3,'a5.3')
--insert into #test2(起点,kn) values(6.6,'a6.6')
--insert into #test2(起点,kn) values(6.1,'a6.1')

-- 先求表 #test2 的起点的最小值,用函数 floor(起点),如1.1,1.2,就取为1,min(起点)=1.1,如下:
select min(起点)as 起点,floor(起点)as 桩号 from #test2 group by floor(起点)
--再把求min(起点)后的 kn 数据取回来,如下:
select t1.*,t2.kn from (select min(起点)as 起点,floor(起点)as 桩号 from #test2 group by floor(起点))t1,#test2 t2 where t1.起点=t2.起点
--上面的是过程,实际,只要下面的
--把上表打包为t3,就出现下面的 update,
update #test1 set kr=kn from
 (select t1.*,t2.kn from (select min(起点)as 起点,floor(起点)as 桩号 from #test2 group by floor(起点))t1,#test2 t2 where t1.起点=t2.起点)t3
  where #test1.桩号=t3.桩号
我没数据,不知道实际测试速度。

[此贴子已经被作者于2016-7-10 18:19编辑过]

2016-07-10 18:16
mywisdom88
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
--create table #test1(桩号 int,kr varchar(10))
--insert into #test1(桩号,kr) values(1,'a1')
--insert into #test1(桩号,kr) values(2,'a2')
--insert into #test1(桩号,kr) values(3,'a3')
--insert into #test1(桩号,kr) values(4,'a4')
--insert into #test1(桩号,kr) values(5,'a5')
--insert into #test1(桩号,kr) values(6,'a6')

--create table #test2(起点 numeric(10,1),kn varchar(10))
--insert into #test2(起点,kn) values(1.1,'a1.1')
--insert into #test2(起点,kn) values(1.2,'a1.2')
--insert into #test2(起点,kn) values(2.2,'a2.2')
--insert into #test2(起点,kn) values(3.1,'a3.1')
--insert into #test2(起点,kn) values(4.5,'a4.5')
--insert into #test2(起点,kn) values(5.3,'a5.3')
--insert into #test2(起点,kn) values(6.6,'a6.6')
--insert into #test2(起点,kn) values(6.1,'a6.1')
--测试条件是SQL2000,以上数测试数据,取 #test2.起点 最小整数 与 @test1.桩号 匹配
2016-07-10 18:25
mywisdom88
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
update cal2 as t1 left join hdm as t2 on t1.起点>=t2.桩号set t1.K=t2.kr
你以前这个,有问题的,如果出现 2.1,2.5这样的数据,你会更新2次
2016-07-10 18:29
colorto
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2014-8-1
得分:0 
谢谢版主的指导,但是还是有一个问题  我的表一cal2 第一列有时候并不是按照123456的顺序来的,有时候是1 3 6  8 9 12 呢?floor是取整函数不合适,例如查询4.4对应的函数,先取整为4,但是表A中只有3 和6对应的值 这时候就无法匹配,麻烦请看我的图2,也就是说我要查找小于4.4的最大值对应的数值,这个小于4.4的最大值不一定是4

这个题必需要两个表格联合起来查询 生成笛卡尔积,但是笛卡尔积的行数是两个表的乘积 生成的表格非常大影响速度 超过十多秒不能容忍
根据你提供的思路我写了如下的sql语句 但是速度还是不够理想
DoCmd.RunSQL "select t1.起点 as 起点,max(t2.桩号) as 桩号 INTO B from cal as t1 left join hdm as t2 on t1.起点>t2.桩号 group by t1.起点"
DoCmd.RunSQL "update cal as a left join  b on a.起点=b.起点 set a.终点=b.桩号"
第一局生成两列,第一列是要查询的起点,第二列是小于起点的最大值;第二局是根据第一局的表格进行更新匹配

[此贴子已经被作者于2016-7-11 00:04编辑过]

2016-07-10 23:53
colorto
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2014-8-1
得分:0 
这个是数值分析最基本的一个查询,不应该是这么复杂的sql语句,不然从桩数值分析的角度看,sql比excel弱爆了,要知道在excel中至少有三种方法可以实现这个功能,例如lookup vlookup offset match rank函数都可以实现,而且速度几乎为零
2016-07-11 00:06



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-466800-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.258199 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved