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);
将返回如下输出: enter image description here
答案 0 :(得分:0)
虽然这可能不是一个完整的答案(仍在制定细节),但如果你从这开始,你将得到一个按升序排列的最佳匹配车辆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