我有一个记录和字段的表T.我想创建一个新字段,并用查找另一个表L的结果填充它。这意味着我将使用T中的一个或多个字段作为外键。在SQL中,我可以使用表L的JOIN更新表T中新创建的字段。相反,Matlab在执行join
时没有更新现有表;这会创建一个全新的表,然后用它来替换原始的表T.看起来很多数据复制来填充一个字段。这是避免引擎盖下的吗?是否存在避免这种情况的代码设计模式或习惯用法,但仍然具有合理的可读性并且不会过多地牺牲代码的紧凑性?
虽然我在join
的上下文中提到了这个问题,但我对在Matlab联接的所有变体中避免表复制的策略感兴趣。
我将描述一个示例,说明Table1
中ForeignKey
中的每条记录如何使用Data
来查找Table2
中的 Table1
-----------------------------
SomeField NewField ForeignKey
--------- -------- ----------
someData1 dummy a
someData2 dummy b
someData3 dummy a
someData4 dummy b
someData5 dummy a
Table2
--------
Key Data
--- ----
a apple
b banana
。
Data
以下SQL代码执行查找。然后,SomeField
字段中的条目与Table1
中的字段NewField
的内容连接,并存储到字段UPDATE Table1 INNER JOIN Table2
ON Table1.ForeignKey = Table2.Key
SET Table1.NewField = Table1.SomeField & Table2.Data
中。
Table1
更新的 Table1
------------------------------------
SomeField NewField ForeignKey
--------- --------------- ----------
someData1 someData1apple a
someData2 someData2banana b
someData3 someData3apple a
someData4 someData4banana b
someData5 someData5apple a
是:
Table INNER JOIN Table2
有趣的是,Table1
实际上并未创建。仅“虚拟”创建才能进行更新JOIN
的计算。相比之下,Matlab的data: { sections: [ { fields: []}]}
创建了实际的连接表,并且需要单独的操作来进行计算。
答案 0 :(得分:1)
我不是桌面专家,但我可以深入了解MATLAB如何使用这种类型的数据。
MATLAB table
对象包含每列的矩阵。
在MATLAB中复制矩阵不会复制数据。 MATLAB使用延迟复制。这意味着副本引用与原始数据相同的数据(直到更改副本或原始文件,此时进行复制)。此行为已有详细记录(1),(2)。
因此,使用其他表中的整个列创建新表将导致复制矩阵,但这些副本不会导致矩阵内容的任何实际复制,新表引用数据原始表。
但是,如果更改了列中的任何值,则需要复制整个列以避免其他表看到相同的更改。引用是内部的和临时的,对用户是不可见的。出于所有目的和目的,看起来新表包含原始数据的副本。
但是,如果join
操作导致交换或删除行,则所有这些都是一个有争议的问题。数据将被复制。
答案 1 :(得分:1)
您正在进行的操作必须如下所示:
table1 = table({'someData1';'someData2';'someData3';'someData4';'someData5'},...
{'a';'b';'a';'b';'a'},'VariableNames',{'SomeField','ForeignKey'});
table2 = table({'a';'b'},{'apple';'banana'},'VariableNames',{'Key','Data'});
table3 = join(table1,table2,'LeftKeys','ForeignKey','RightKeys','Key')
这会产生下表:
SomeField ForeignKey Data
___________ __________ ________
'someData1' 'a' 'apple'
'someData2' 'b' 'banana'
'someData3' 'a' 'apple'
'someData4' 'b' 'banana'
'someData5' 'a' 'apple'
然后,您要对列SomeField
和Data
进行某种操作。
我认为已经添加了这个join
函数,以便熟悉SQL但不太熟悉MATLAB语法的人使用。
如果您仍然担心复制大量数据(正如我所提到的,由于延迟复制而不是这种情况),您可以使用以下基于集合的操作获取上面的列Data
: / p>
[~,index] = ismember(table1.ForeignKey,table2.Key);
data = table2.Data(index);
此处,data
是一个与table3.Data
相同的单元格数组。在任何情况下,此处创建的index
值都是SQL为此JOIN操作在内部创建的值。如果table1.ForeignKey
不在table2.Key
中,则相应的index
值为0(MATLAB索引从1开始)。在这种情况下,您不能直接使用index
进行索引,您需要使用额外级别的索引才能获得有效行:
[valid,index] = ismember(table1.ForeignKey,table2.Key);
data1 = table1.SomeField(valid)
data2 = table2.Data(index(valid));
请注意,table/join
以完全相同的方式使用ismember
,然后复制左表(由于延迟复制,导致副本引用输入表中的数据),并添加列它是正确的表格。