mysql - 如何找到最接近的值并将其与记录合并?

标签 mysql sql

基本上我想要做的是找到具有最接近值的记录,从中提取一个值并添加创建包含该值的记录。我不知道这是否可能。

所以我的记录看起来像这样

Wire_tag|lenght|place|
----------------------
W1      |2     |closet
W2      |2.5   |NULL
W3      |3     |NULL
W4      |4     |conveyor
W5      |5     |NULL

我想要实现的目标是在列位置不为空的情况下分配wire_tag,并在列位置与空不同的情况下将最接近的长度值分配给连线。所以我想要达到的结果是这样的

Wire_tag|lenght|place   |wire_assign
------------------------------------
W1      |2.5   |closet  |W2
W4      |3     |conveyor|W3
W4      |5     |conveyor|W5

最佳答案

这里有两种方法,第一种(很好的)方法依赖于使用公共(public)表表达式,我不确定这些方法在您所使用的 MySQL 版本中是否可用,所以第二个版本不使用任何“花哨的”SQL。

首先我创建了一个临时表,你不需要这一步(而且这也不是 MySQL 语法):

CREATE TABLE #wires (
    wire_tag VARCHAR(50),
    lenght NUMERIC(9,1),
    place VARCHAR(50));
INSERT INTO #wires SELECT 'W1', 2, 'closet';
INSERT INTO #wires SELECT 'W2', 2.5, NULL;
INSERT INTO #wires SELECT 'W3', 3, NULL;
INSERT INTO #wires SELECT 'W4', 4, 'conveyor';
INSERT INTO #wires SELECT 'W5', 5, NULL;

因此,在下面的查询中将 #wires 替换为您的实际表名称:

--Nice way
WITH distances AS (
    SELECT
        w.wire_tag,
        w2.lenght,
        w.place,
        w2.wire_tag AS wire_assign,
        ABS(w2.lenght - w.lenght) AS distance
    FROM
        #wires w
        LEFT JOIN #wires w2 ON w2.place IS NULL
    WHERE
        w.place IS NOT NULL),
min_distances AS (
    SELECT
        wire_tag,
        MIN(distance) AS min_distance
    FROM
        distances
    GROUP BY
        wire_tag)
SELECT
    d.wire_tag,
    d.lenght,
    d.place,
    d.wire_assign
FROM
    distances d
    INNER JOIN min_distances m ON m.wire_tag = d.wire_tag AND m.min_distance = d.distance;

--Nasty way 
SELECT
    y.wire_tag,
    y.lenght,
    y.place,
    y.wire_assign
FROM
    (SELECT
        w.wire_tag,
        w2.lenght,
        w.place,
        w2.wire_tag AS wire_assign,
        ABS(w2.lenght - w.lenght) AS distance
    FROM
        #wires w
        LEFT JOIN #wires w2 ON w2.place IS NULL
    WHERE
        w.place IS NOT NULL) y
    INNER JOIN (
        SELECT
            wire_tag,
            MIN(distance) AS min_distance
        FROM
            (SELECT
                w1.wire_tag,
                ABS(w2.lenght - w1.lenght) AS distance
            FROM
                #wires w1
                LEFT JOIN #wires w2 ON w2.place IS NULL
            WHERE
                w1.place IS NOT NULL) x
        GROUP BY
            wire_tag) m ON m.wire_tag = y.wire_tag AND m.min_distance = y.distance;

两种方法给出相同的结果:

wire_tag    lenght  place   wire_assign
W1          2.5     closet      W2
W4          3.0     conveyor    W3
W4          5.0     conveyor    W5

关于mysql - 如何找到最接近的值并将其与记录合并?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54458097/

相关文章:

mysql - 我将如何构建此数据库以实现功能?

mysql_tzinfo_to_sql ORDER BY 错误

sql - 为什么 Oracle 认为这个查询格式错误?

javascript - 如何在 Node js中包装长sql语句

sql - 使用 SQL 清理相同的行

sql - 使用 PIVOT 选择列值作为列

mysql - 如何防止在数据库中手动编辑数据?

mysql - 我需要一个 SQL 查询,它根据 C 列中是否存在字符串从 A 列或 B 列中进行选择

mysql - 将 MMM-YY 字符串转换为可排序日期格式

mysql - 如何创建一个表,其中一列包含具有不同 id 的所有行的相同值?(请参阅布局以了解清楚)