【发布时间】:2013-04-07 06:18:20
【问题描述】:
我正在寻找以下内容:
需要符合以下条件的行:设备列的通用值和两个表中接口列的前三个字符。
然后从Table1中匹配上述条件的行,取出Specified列的值,并将其存储在上述条件匹配的行的Table2的Avgin列中。
有人可以帮我吗?数据库是 MySQL。
【问题讨论】:
标签: mysql sql sql-update
我正在寻找以下内容:
需要符合以下条件的行:设备列的通用值和两个表中接口列的前三个字符。
然后从Table1中匹配上述条件的行,取出Specified列的值,并将其存储在上述条件匹配的行的Table2的Avgin列中。
有人可以帮我吗?数据库是 MySQL。
【问题讨论】:
标签: mysql sql sql-update
如果有多个匹配项,则仅使用第一个。
如果没有,将使用 null。如果您想要其他内容,请使用ifnull()。
UPDATE
table2
SET
avgin=ifnull(
(
SELECT
Specified
FROM
table1
WHERE
table1.Device=table2.Device
AND substring(table1.Interface,1,3)=substring(table2.Interface,1,3)
LIMIT 1
),
'default value'
)
编辑:添加ifnull()
【讨论】:
UPDATE 和 JOIN 是你需要的,像这样:
UPDATE Table2 AS t2
INNER JOIN table1 AS t1 ON LEFT(t2.Interface, 3) = LEFT(t1.Interface, 3)
AND t1.Device = t2.Device
SET t2.Avgin = t1.specified;
使用JOIN 条件,正如您在问题中解释的那样:
LEFT(t2.Interface, 3) = LEFT(t1.Interface, 3)
AND
t1.Device = t2.Device
LEFT 将为您提供两个表格左侧的前 3 个字符。
在这里查看它的实际效果:
这将使table2 看起来像:
| CID | DEVICE | INTERFACE | AVGIN |
---------------------------------------------------
| HDC-HKG-R01 | HDC-TBONE-P1 | P09/0/0 | 121.36 |
| OCB-OCD-R01 | OCB-PE1 | Gi5/2 | 0.17 |
| HDC-BSA-R01 | HDC-TBONE-P1 | Se9/2/0 | (null) |
【讨论】:
用它来确认你得到了你期望的行(即之前更新任何东西):
SELECT
t1.Specified
FROM
table2 t2
INNER JOIN table1 t1
ON t1.device = t2.device
AND LEFT(t1.interface,3) = LEFT(t2.interface,3)
然后,假设这是对的:
UPDATE table2 t2
INNER JOIN table1 t1
ON t1.device = t2.device
AND LEFT(t1.interface,3) = LEFT(t2.interface,3)
SET t2.Avgin = ifnull(t1.specified,'Default Value For When t1.Specified is NULL')
请注意,我们使用的是 INNER 连接...这意味着 table2 中在 table1 中没有对应行的行将从结果中丢弃(这是您想要的)。
IFNULL 将允许您在连接成功的情况下使用默认值(因为 device 和 interface 的前三个字符对两个表都是通用的),但 table1.specified 具有 NULL 值为那一行。
【讨论】:
ifnull() 实现将不起作用,因为您使用的是INNER JOIN,从而使不对应的行超出范围。你可以尝试使用LEFT JOIN。
device 和interface 上的INNER JOIN 成功时,列specified 可以为NULL。即这样,当table1 中不存在匹配项时,table2.avgin 保留为空,或者如果该列不为空,则更新为t1.specified 包含的任何列,或者更新为table1.specified 时硬编码的任何默认值一片空白。归结为 OP 真正想要的......他的评论“但是我应该如何以及在哪里使用 ifnull()”几乎不是一个详细的需求规范 ;-),但我相信这个答案涵盖了所有基础。