在履历表里查找满足条件的记录的效率问题(重发)

funsuzhou 2009-07-13 03:20:23
现有履历表XRECE_HCSZ_C_PRICE(别名REP,CUTANK PRICE 为DECIMAL(28,8),其它字符型):
CODE CUST NOUBA TDATE CUTANK PRICE
AB50052 CHT001U CDP001U 20090115 3000.00000000 5.00000000
AB50052 CHT001U CDP001U 20090115 4000.00000000 6.00000000
AB50052 CHT001U CDP001U 20090115 4000.00000000 5.50000000
AB50052 CHT001U CDP001U 20090109 2000.00000000 4.00000000
AB50052 CHT001U CDP001U 20090101 0.00000000 0.07700000
AB50052 CHT001U CDP001U 20090101 0.00000000 1.00000000
AB50052 CHT001U CDP001U 20090101 1000.00000000 2.00000000
AB50052 CHT001U CDP001U 20090101 1000.00000000 3.00000000

还有受订表XRECE(别名RE),含有与履历表一样的字段。我想达到这样的目的(用1条SQL语句实现):
SELECT RE.CODE,RE.CUST,RE.NOUBA,RE.TDATE,RE.CUTANK,REP.PRICE
FROM ......

抽取逻辑:
当受订表CODE CUST NOUBA TDATE CUTANK分别取'AB50052','CHT001U','CDP001U','20090101',0时,REP.PRICE能返回0.07700000
当受订表CODE CUST NOUBA TDATE CUTANK分别取'AB50052','CHT001U','CDP001U','20090101',1000时,REP.PRICE能返回2
当受订表CODE CUST NOUBA TDATE CUTANK分别取'AB50052','CHT001U','CDP001U','20090110',1000时,REP.PRICE能返回0
当受订表CODE CUST NOUBA TDATE CUTANK分别取'AB50052','CHT001U','CDP001U','20090115',3500时,REP.PRICE能返回5

即相同的CODE CUST NOUBA记录里面先找REP.TDATE<=RE.TDATE中最大的REP.TDATE,然后再在筛选后的记录集里面找REP.CUTANK<=RE.CUTANK中最大的REP.CUTANK,然后再在筛选后的记录集里面找最小的REP.PRICE。
如果有不满足任何一个条件的则返回0.

想了好久,不知道怎么写,我曾经写过一个自定义函数,但运行起来效率很低。所以我想能否用1句SQL语句实现?
...全文
92 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
funsuzhou 2009-07-14
  • 打赏
  • 举报
回复
To libin_ftsafe:
今天早上我一到公司就测试了一下,可以了,这样的写法看上去好像效率不怎么高,但是可以实现了,谢谢。
feixianxxx 2009-07-13
  • 打赏
  • 举报
回复

CREATE TABLE XRECE_HCSZ_C_PRICE(
CODE VARCHAR(10),
CUST VARCHAR(10),
NOUBA VARCHAR(10),
TDATE VARCHAR(10),
CUTANK DECIMAL(28,8),
PRICE DECIMAL(28,8))
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',3000.00000000,5.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',4000.00000000,6.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',4000.00000000,5.50000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090109',2000.00000000,4.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101', 0.00000000,0.07700000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101', 0.00000000,1.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101',1000.00000000,2.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101',1000.00000000,3.00000000)

CREATE TABLE XRECE(
CODE VARCHAR(10),
CUST VARCHAR(10),
NOUBA VARCHAR(10),
TDATE VARCHAR(10),
CUTANK DECIMAL(28,8))
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090101',0
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090101',1000
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090110',1000
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090115',3500
GO



SELECT RE.CODE,RE.CUST,RE.NOUBA,RE.TDATE,RE.CUTANK,
REP.PRICE
FROM XRECE re ,XRECE_HCSZ_C_PRICE rep
where re.CODE=rep.code and re.Cust=rep.cust and re.NOUBA=rep.NOUBA
and re.TDATE=rep.TDATE and re.CUTANK=rep.CUTANK

/*
(1 行受影响)

(1 行受影响)
CODE CUST NOUBA TDATE CUTANK PRICE
---------- ---------- ---------- ---------- --------------------------------------- ---------------------------------------
AB50052 CHT001U CDP001U 20090101 0.00000000 0.07700000
AB50052 CHT001U CDP001U 20090101 0.00000000 1.00000000
AB50052 CHT001U CDP001U 20090101 1000.00000000 2.00000000
AB50052 CHT001U CDP001U 20090101 1000.00000000 3.00000000

(4 行受影响)

*/
claro 2009-07-13
  • 打赏
  • 举报
回复
帮顶
子陌红尘 2009-07-13
  • 打赏
  • 举报
回复
CREATE TABLE XRECE_HCSZ_C_PRICE(
CODE VARCHAR(10),
CUST VARCHAR(10),
NOUBA VARCHAR(10),
TDATE VARCHAR(10),
CUTANK DECIMAL(28,8),
PRICE DECIMAL(28,8))
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',3000.00000000,5.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',4000.00000000,6.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',4000.00000000,5.50000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090109',2000.00000000,4.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101', 0.00000000,0.07700000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101', 0.00000000,1.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101',1000.00000000,2.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101',1000.00000000,3.00000000)

CREATE TABLE XRECE(
CODE VARCHAR(10),
CUST VARCHAR(10),
NOUBA VARCHAR(10),
TDATE VARCHAR(10),
CUTANK DECIMAL(28,8))
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090101',0
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090101',1000
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090110',1000
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090115',3500
GO


SELECT
RE.CODE,RE.CUST,RE.NOUBA,RE.TDATE,RE.CUTANK,
ISNULL((SELECT
TOP 1 PRICE
FROM
XRECE_HCSZ_C_PRICE
WHERE
CODE=RE.CODE AND CUST=RE.CUST AND NOUBA=RE.NOUBA AND TDATE<=RE.TDATE AND CUTANK<=RE.CUTANK
AND
TDATE= (SELECT MAX(TDATE) FROM XRECE_HCSZ_C_PRICE
WHERE CODE=RE.CODE AND CUST=RE.CUST AND NOUBA=RE.NOUBA AND TDATE<=RE.TDATE)
AND
CUTANK=(SELECT MAX(CUTANK) FROM XRECE_HCSZ_C_PRICE
WHERE CODE=RE.CODE AND CUST=RE.CUST AND NOUBA=RE.NOUBA AND TDATE<=RE.TDATE AND CUTANK<=RE.CUTANK)
ORDER BY
TDATE DESC,CUTANK DESC,PRICE),0) AS PRICE
FROM
XRECE RE
GO

/*
CODE CUST NOUBA TDATE CUTANK PRICE
---------- ---------- ---------- ---------- ------------------------------ ------------------------------
AB50052 CHT001U CDP001U 20090101 .00000000 .07700000
AB50052 CHT001U CDP001U 20090101 1000.00000000 2.00000000
AB50052 CHT001U CDP001U 20090110 1000.00000000 .00000000
AB50052 CHT001U CDP001U 20090115 3500.00000000 5.00000000
*/


DROP TABLE XRECE_HCSZ_C_PRICE,XRECE
GO
funsuzhou 2009-07-13
  • 打赏
  • 举报
回复
To libin_ftsafe:
您的写法把AB50052 CHT001U CDP001U 20090109 2000.00000000 4.00000000
这条记录都给滤掉了,可能是我没有说清楚,不好意思。
funsuzhou 2009-07-13
  • 打赏
  • 举报
回复
To libin_ftsafe:
我举个例子吧:
当受订表CODE CUST NOUBA TDATE CUTANK分别取'AB50052','CHT001U','CDP001U','20090110',1000时,按照您的回复,取出的是2,
而我是要求这样取:
TDATE<='20090110',符合条件的记录有:
AB50052 CHT001U CDP001U 20090109 2000.00000000 4.00000000
AB50052 CHT001U CDP001U 20090101 0.00000000 0.07700000
AB50052 CHT001U CDP001U 20090101 0.00000000 1.00000000
AB50052 CHT001U CDP001U 20090101 1000.00000000 2.00000000
AB50052 CHT001U CDP001U 20090101 1000.00000000 3.00000000
最大的TDATE是'20090109'
然后在前3个字段相同、TDATE='20090109'的记录里进一步找,因为2000>1000了,所以没有符合条件的记录,返回0
子陌红尘 2009-07-13
  • 打赏
  • 举报
回复
楼主没有把逻辑关系描述清楚,这三个字段的关系不是这么简单吧?

ORDER BY TDATE DESC,CUTANK DESC,PRICE

--先按照TDATE倒序排列,日期最大的在最前面;
--然后按照CUTANK倒序排列,相同日期中CUTANK最大的在最前面;
--最后按照PRICE排序,TDATE和CUTANK相同的记录中,PRICE最小的排在最前面。

以上的排序方式应该是符合楼主描述的。
funsuzhou 2009-07-13
  • 打赏
  • 举报
回复
我就是觉得不是那么容易才在这里发帖,所以要请教高手了!
jyh_baoding 2009-07-13
  • 打赏
  • 举报
回复
写查询语句,根据分类的大小,决定分类的小后!!
funsuzhou 2009-07-13
  • 打赏
  • 举报
回复
TO libin_ftsafe:
谢谢您的回复,但是您的回复不符合我的要求。
我是要先找到符合条件的最大的REP.TDATE,然后在符合条件的记录(REP.TDATE已经固定下来了)里再找符合条件的最大的REP.CUTANK,然后再符合条件的记录(REP.TDATE和REP.CUTANK已经固定下来了)里找最小的REP.PRICE
当找不到符合条件的REP.TDATE或REP.CUTANK时,返回0
mousefog 2009-07-13
  • 打赏
  • 举报
回复
学习
funsuzhou 2009-07-13
  • 打赏
  • 举报
回复
0就是当找不到TDATE或CUTANK时取0
子陌红尘 2009-07-13
  • 打赏
  • 举报
回复
CREATE TABLE XRECE_HCSZ_C_PRICE(
CODE VARCHAR(10),
CUST VARCHAR(10),
NOUBA VARCHAR(10),
TDATE VARCHAR(10),
CUTANK DECIMAL(28,8),
PRICE DECIMAL(28,8))
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',3000.00000000,5.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',4000.00000000,6.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090115',4000.00000000,5.50000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090109',2000.00000000,4.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101', 0.00000000,0.07700000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101', 0.00000000,1.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101',1000.00000000,2.00000000)
INSERT INTO XRECE_HCSZ_C_PRICE VALUES('AB50052','CHT001U','CDP001U','20090101',1000.00000000,3.00000000)

CREATE TABLE XRECE(
CODE VARCHAR(10),
CUST VARCHAR(10),
NOUBA VARCHAR(10),
TDATE VARCHAR(10),
CUTANK DECIMAL(28,8))
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090101',0
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090101',1000
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090110',1000
INSERT INTO XRECE SELECT 'AB50052','CHT001U','CDP001U','20090115',3500
GO

SELECT
RE.CODE,RE.CUST,RE.NOUBA,RE.TDATE,RE.CUTANK,
ISNULL((SELECT
TOP 1 PRICE
FROM
XRECE_HCSZ_C_PRICE
WHERE
CODE=RE.CODE AND CUST=RE.CUST AND NOUBA=RE.NOUBA AND TDATE<=RE.TDATE AND CUTANK<=RE.CUTANK
ORDER BY
TDATE DESC,CUTANK DESC,PRICE),0) AS PRICE
FROM
XRECE RE
GO

/*
CODE CUST NOUBA TDATE CUTANK PRICE
---------- ---------- ---------- ---------- ------------------------------ ------------------------------
AB50052 CHT001U CDP001U 20090101 .00000000 .07700000
AB50052 CHT001U CDP001U 20090101 1000.00000000 2.00000000
AB50052 CHT001U CDP001U 20090110 1000.00000000 2.00000000
AB50052 CHT001U CDP001U 20090115 3500.00000000 5.00000000
*/

-- 0这个取值的规则没分析清楚

DROP TABLE XRECE_HCSZ_C_PRICE,XRECE
GO
brio8425 2009-07-13
  • 打赏
  • 举报
回复
技术性路过!~
子陌红尘 2009-07-13
  • 打赏
  • 举报
回复
SELECT
RE.CODE,RE.CUST,RE.NOUBA,RE.TDATE,RE.CUTANK,
ISNULL(SELECT
TOP 1 PRICE
FROM
XRECE_HCSZ_C_PRICE
WHERE
CODE=RE.CODE AND CUST=RE.CUST AND NOUBA=RE.NOUBA AND TDATE<=RE.TDATE
ORDER BY
TDATE DESC,CUTANK DESC,PRICE),0) AS PRICE
FROM
XRECE RE
feixianxxx 2009-07-13
  • 打赏
  • 举报
回复
SELECT RE.CODE,RE.CUST,RE.NOUBA,RE.TDATE,RE.CUTANK,
REP.PRICE
FROM XRECE re ,XRECE_HCSZ_C_PRICE rep
where re.CODE=rep.code and re.Cust=rep.cust and re.NOUBA=rep.NOUBA
and re.TDATE=rep.TDATE and re.CUTANK=rep.CUTANK
feixianxxx 2009-07-13
  • 打赏
  • 举报
回复
SELECT RE.CODE,RE.CUST,RE.NOUBA,RE.TDATE,RE.CUTANK,
REP.PRICE
FROM re ,rep
where re.CODE=rep.code and re.Cust=rep.cust and re.NOUBA=rep.NOUBA
and re.TDATE=rep.TDATE and re.CUTANK=rep.CUTANK

这样就可以了
funsuzhou 2009-07-13
  • 打赏
  • 举报
回复
回1楼,我想了好久了,水平有限,真是不好意思。
sdhdy 2009-07-13
  • 打赏
  • 举报
回复
那得用CASE WHEN THEN 实现,自己写一个吧。

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧