使用其他行的数据更新同一表中的行 SQL
Posted
技术标签:
【中文标题】使用其他行的数据更新同一表中的行 SQL【英文标题】:Update row SQL in same table with data from other row 【发布时间】:2021-04-14 12:33:53 【问题描述】:我坚持使用 SQL 查询来更新同一个表中的不同行。但是 1 行必须从具有相同参考 ID (bst__ref
) 的另一行获取数据。
当前表bstlyn__
A | B | C | D | E | F | G |
---|---|---|---|---|---|---|
157035 | 1/01/1980 | 2/04/2021 | 117210 | N | 0 | N |
157035 | 1/01/1980 | 25/03/2021 | 128078 | N | 0 | N |
157035 | 1/01/1980 | 25/03/2021 | 128078 | N | 0 | N |
157036 | 1/01/1980 | 12/04/2021 | 117022 | N | 0 | N |
157036 | 1/01/1980 | 12/04/2021 | 117034 | N | 0 | N |
157036 | 1/01/1980 | 9/04/2021 | 128078 | N | 0 | N |
当前 SQL 查询
UPDATE bstlyn__ SET G = 'Y', F = 'N', B = C WHERE E = 'N' AND F = '0'
这会导致将所有vrz__dat
行更改为与vrzv_dat
中相同的值。但正如您在同一个bst__ref
中看到的,所有afg__ref
的值为128078 的vrzv_dat 具有不同的vrzv_dat
。这应该与bst__ref
中没有afg__ref
128078 的(第一)行相同的日期/vrz__dat
。
所以,运行上面的查询后,我得到:
bst__ref (A) | vrz__dat (B) | vrzv_dat (C) | afg__ref (D) | fiat____ (E) | fac__tst (F) | vrz__tst (G) |
---|---|---|---|---|---|---|
157035 | 2/04/2021 | 2/04/2021 | 117210 | N | N | Y |
157035 | 25/03/2021 | 25/03/2021 | 128078 | N | N | Y |
157035 | 25/03/2021 | 25/03/2021 | 128078 | N | N | Y |
157036 | 12/04/2021 | 12/04/2021 | 117022 | N | N | Y |
157036 | 12/04/2021 | 12/04/2021 | 117034 | N | N | Y |
157036 | 9/04/2021 | 9/04/2021 | 128078 | N | N | Y |
但应该是:
bst__ref | vrz__dat | vrzv_dat | afg__ref | fiat____ | fac__tst | vrz__tst |
---|---|---|---|---|---|---|
157035 | 2/04/2021 | 2/04/2021 | 117210 | N | N | Y |
157035 | 2/04/2021 | 25/03/2021 | 128078 | N | N | Y |
157035 | 2/04/2021 | 25/03/2021 | 128078 | N | N | Y |
157036 | 12/04/2021 | 12/04/2021 | 117022 | N | N | Y |
157036 | 12/04/2021 | 12/04/2021 | 117034 | N | N | Y |
157036 | 12/04/2021 | 9/04/2021 | 128078 | N | N | Y |
我到底如何只使用 SQL 来做到这一点? 谢谢!
【问题讨论】:
您使用的是哪个 dbms? FireDAC / Phys / ODBC / Microsoft / SQL Server Native Client 11.0 什么定义了“第一行” 你如何订购它们? @Charlieface no Idea tbh,但通常第一行永远不会出现在afg__ref
128078
如果您无法定义我们如何获得第一行,我们该如何解决?请记住,表没有固有的顺序,每次返回的结果都可能不同,而没有明确的顺序
【参考方案1】:
您需要关联回同一张表。有多种方法可以做到这一点,您似乎想专门针对单个值执行此操作,所以如果我理解正确,您可以尝试一下
update b set
vrz__tst = 'Y',
fac__tst = 'N',
vrz__dat =
case when afg_ref=128078 then
(select Min(vrzv_dat) from bstlyn__ b2 where b2.bst_ref=b.bst_ref)
else vrzv_dat end
from bstlyn__ b
where fiat____ = 'N' and fac__tst = '0'
【讨论】:
嗯,如果您的意思是Min(vrzv_dat)
,那么它的输出与使用我的查询相同。如果您的意思是Min(vrz__dat)
,那么它不会更改任何具有afg__ref
128078 的行。它应该将这些也从没有afg__ref
128078 的1 行更改为相同的vrzv_dat
(但共享相同的bst__ref
)。很难解释,不是吗... :-)
是的,也许我的意思是——我见过更容易阅读的查询。如果会更好,对于示例数据示例,您只需命名列 A、B、C 等:)
更改了上表中的列名,希望现在更容易理解。所以; B 必须成为与 C 相同的值,但是当 D 具有值“128078”时,它必须搜索 A 的相同行,然后从第一行(或 D 中没有“128078”的行中选择日期) 来自 C 列并更新它。因此,来自同一列 A 的所有行都需要在列 C 中具有相同的值
啊哈!我想我找到了; update b set vrz__tst = 'Y', fac__tst = 'N', vrz__dat = case when afg__ref='128078' then (select Max(vrzv_dat) from bstlyn__ b2 where b2.bst__ref=b.bst__ref) else vrzv_dat end from bstlyn__ b where fiat____ = 'N' and fac__tst = '0'
当然,在这种情况下,日期总是必须更高,但在我的用例中(通常)总是这样。【参考方案2】:
你可以使用这个表两次,你只需要在子查询中给表起别名。然后对每个相同的 A 代码只执行第一个检索
试试这个代码:
UPDATE bstlyn__ t, (SELECT DISTINCT A,B,C,D,E,F,G
FROM bstlyn__ ) t1
SET t.B = t1.C, G = 'Y', F = 'N'
WHERE t.A= t1.A
【讨论】:
我试过UPDATE bstlyn__ SET vrz__tst = 'Y', fac__tst = 'N', vrz__dat = (SELECT vrzv_dat FROM (SELECT TOP 1 vrzv_dat FROM bstlyn__ ORDER BY bst__ref) t) WHERE fiat____ = 'N' AND fac__tst = '0'
但是它需要表格的第一个(日期为 4/05/2012)
对您的答案如何工作的一些解释将极大地批准这个答案。 OP 应该能够从中学习,而不仅仅是复制/过去并很高兴它有效。以上是关于使用其他行的数据更新同一表中的行 SQL的主要内容,如果未能解决你的问题,请参考以下文章
在 DataGridView 中显示数据表 SQL RealTime