繁体   English   中英

返回最接近要搜索的值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM