[英]return the closest value to value being searched
enter code here
我需要先按类型对车辆进行配对,然后再对油耗进行配对。 燃油消耗可能不匹配,在这种情况下,选择最接近的值。 同一辆车不能多次配对。 我正在谈论的数据类型示例如下
create table #table1
(
vehicleid varchar(2),
typed varchar(5),
fuelconsumption int
)
create table #table2
(
vehicleid varchar(2),
typed varchar(5),
fuelconsumption int
)
INSERT INTO #table1 VALUES('x1','car',5);
INSERT INTO #table1 VALUES('x2','car',4);
INSERT INTO #table1 VALUES('x3','car',8);
INSERT INTO #table2 VALUES('b1','car',7);
INSERT INTO #table2 VALUES('b2','car',8);
INSERT INTO #table2 VALUES('b3','car',9);
INSERT INTO #table2 VALUES('b4','car',10);
INSERT INTO #table2 VALUES('b5','car',11);
INSERT INTO #table2 VALUES('b6','truck',15);
INSERT INTO #table2 VALUES('b7','truck',4);
它将返回如下输出: 在此处输入图像描述
尽管这可能不是一个完整的答案(仍在计算详细信息),但是如果您以此开头,则会获得按升序排列的最佳匹配车辆ID的列表:
SELECT baseID = ibase.vehicleid,
matchID = im.vehicleid,
rowNum = ROW_NUMBER()
OVER (PARTITION BY ibase.vehicleid
ORDER BY ABS(ibase.fuelconsumption - im.fuelconsumption))
FROM #table1 ibase
INNER JOIN #table2 im ON ibase.typed = im.typed
从这里,您应该能够遍历捡起“ b”型车辆的“第一个”实例
完整答案(注意:我讨厌游标,但这可行):
DROP TABLE #results
CREATE TABLE #results ( vehicleid1 VARCHAR(2), vehicleid2 VARCHAR(2), diff INT, rownum INT )
INSERT INTO #results ( vehicleid1, vehicleid2, diff, rownum )
SELECT baseID = ibase.vehicleid,
matchID = im.vehicleid,
diff = ABS(ibase.fuelconsumption - im.fuelconsumption),
rowNum = ROW_NUMBER()
OVER (
PARTITION BY ibase.vehicleid
ORDER BY ABS(ibase.fuelconsumption - im.fuelconsumption))
FROM #table1 ibase
INNER JOIN #table2 im ON ibase.typed = im.typed
-- The cursor ensures we get the real best match so we do not accidentally
-- assign a best match which is a _better_ match for another vehicle
DECLARE CUR_ CURSOR FOR SELECT vehicleid1 FROM #results ORDER BY diff
DECLARE @id VARCHAR(2)
OPEN CUR_
FETCH CUR_ INTO @id
WHILE @@FETCH_STATUS = 0
BEGIN
-- Remove all matches other than the BEST match
DELETE r
FROM #results r
WHERE r.vehicleid1 = @id
AND r.rownum <> (SELECT MIN(ir.rownum) FROM #results ir WHERE ir.vehicleid1 = @id)
-- Remove all other matches which use the remaining matched vehicle
DELETE r
FROM #results r
WHERE r.vehicleid1 <> @id
AND r.vehicleid2 = (SELECT ir.vehicleid2 FROM #results ir where ir.vehicleid1 = @id)
FETCH CUR_ INTO @id
END
CLOSE CUR_
DEALLOCATE CUR_
SELECT * FROM #results
非光标解决方案:
DROP TABLE #results
CREATE TABLE #results ( vehicleid1 VARCHAR(2), vehicleid2 VARCHAR(2), diff INT, rownum INT )
INSERT INTO #results ( vehicleid1, vehicleid2, diff, rownum )
SELECT baseID = ibase.vehicleid,
matchID = im.vehicleid,
diff = ABS(ibase.fuelconsumption - im.fuelconsumption),
rowNum = ROW_NUMBER()
OVER (
PARTITION BY ibase.vehicleid
ORDER BY ABS(ibase.fuelconsumption - im.fuelconsumption))
FROM #table1 ibase
INNER JOIN #table2 im ON ibase.typed = im.typed
DECLARE @id VARCHAR(2)
WHILE EXISTS( SELECT vehicleid1 FROM #results GROUP BY vehicleid1 HAVING COUNT(*) > 1 )
BEGIN
SELECT TOP 1
@id = r.vehicleid1
FROM #results r
INNER JOIN (SELECT i.vehicleid1 FROM #results i GROUP BY i.vehicleid1 HAVING COUNT(*) > 1) i
ON r.vehicleid1 = i.vehicleid1
ORDER BY r.diff
-- Remove all matches other than the BEST match
DELETE r
FROM #results r
WHERE r.vehicleid1 = @id
AND r.rownum <> (SELECT MIN(ir.rownum) FROM #results ir WHERE ir.vehicleid1 = @id)
-- Remove all other matches which use the remaining matched vehicle
DELETE r
FROM #results r
WHERE r.vehicleid1 <> @id
AND r.vehicleid2 = (SELECT ir.vehicleid2 FROM #results ir where ir.vehicleid1 = @id)
END
SELECT * FROM #results
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.