一些比较难的sql问题:3(一)

2014-11-24 14:10:00 · 作者: · 浏览: 0
一些比较难的sql问题:3
最近,在 论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。
所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。另外,考虑到前2篇太长,看起来不太方便,所以拆分为第3篇
1、MS-SQL 根据实际所需规格table去比对另一个库存table取浪费最少的数据
情境描述:根据表A里的物料去比对表B,然后表A根据A1括号里两个尺寸浪费最少来将A1替换成最省的物料。
表A用量需求表:Table A
A0(自增长ID) A1(物料编号)
-------------------------------
0 ls001-(900*110)
1 ls002-(200*300)
....
表B库存物料表: B1没有重复,可以当作ID来使用 Table B:
B1(库存物料) B2(规格1) B3(规格2)
----------------------------------------------
ls001-(700*200) 700 200
ls001-(910*140) 910 140
ls001-(920*120) 920 120
... ... ...
ls002-(100*200) 100 200
ls002-(200*350) 200 350
ls002-(220*320) 220 320
...
原理是:ls001取(920*120)的话浪费分别是左边920-900=20,右边120-110=10,总共浪费是30, 是ls001库存规格(700*200),(910*140),(920*120)里浪费最少的,ls002同理。
最后A1字段被替换后的效果如下:
A0(自增长ID) A1(物料编号)
-------------------------------
0 ls001-(920*120)
1 ls002-(220*320)
...
各位有什么好的方案或者算法可分享来学习借鉴一下 ^_^
我的解法:
[sql]
drop table a
drop table b
create table a (a0 int,a1 varchar(100),a2 int,a3 int)
insert into a
SELECT 0,'ls001-(900*110)',900,110 UNION ALL
SELECT 1,'ls002-(200*300)',200,300
create table b (B1 varchar(100),B2 int,B3 int)
insert into b
SELECT 'ls001-(700*200)',700,200 UNION ALL
SELECT 'ls001-(910*140)',910,140 UNION ALL
SELECT 'ls001-(920*120)',920,120 UNION ALL
SELECT 'ls002-(100*200)',100,200 UNION ALL
SELECT 'ls002-(200*350)',200,350 UNION ALL
SELECT 'ls002-(220*320)',220,320
;with t
as
(
select a0,a1,
substring(a1,1,charindex('-',a1)-1) as b1,
a2,a3
--substring(a1,charindex('(',a1)+1, charindex('*',a1)-charindex('(',a1)-1) as b2,
--substring(a1,charindex('*',a1)+1, charindex(')',a1)-charindex('*',a1)-1) as b3
from a
),
tt
as
(
select t.a0,
t.a1,
b.b1,
row_number() over(partition by t.a1
order by abs(t.a2-b.b2) + abs(t.a3 - b.b3)) as rownum
from b
inner join t
on b.b1 like t.b1 + '%'
)
select a0,b1 as a1
from tt
where rownum = 1
/*
a0 a1
0 ls001-(920*120)
1 ls002-(220*320)
*/
2、sql中怎么判断某个字段的值是否连续?
比如:A表的字段AID的值为:1、2、4、5、7、8、10
怎么用sql查询出2、5、8的结果呢?
要查的结果就是查询这组数据从哪里开始不连续的。
我的解法:
[sql]
create table A(AID int)
insert into A(AID)
select 1 union all
select 2 union all
select 4 union all
select 5 union all
select 7 union all
select 8 union all
select 10
select aid
from
(
select a.aid,
(select min(aid) from a aa where aa.aid > a.aid) min_aid
from A
)a
where aid +1 < min_aid
/*
aid
2
5
8
*/
3、关于日期条件出现的奇怪问题。
select top 1 ekeyid,ProbeMaterial,Result,LabTestDate from PatientLabTestResults
where ProbeMaterial='Ca'
and LabTestDate between convert(datetime,2013/1/1) and
convert(datetime,'2013/6/24') order by LabTestDate desc
这样查的出结果,变成
select top 1 ekeyid,ProbeMat