避免在Matlab“join”中复制整个表格

时间:2018-05-03 17:43:56

标签: sql matlab

我有一个记录和字段的表T.我想创建一个新字段,并用查找另一个表L的结果填充它。这意味着我将使用T中的一个或多个字段作为外键。在SQL中,我可以使用表L的JOIN更新表T中新创建的字段。相反,Matlab在执行join时没有更新现有表;这会创建一个全新的表,然后用它来替换原始的表T.看起来很多数据复制来填充一个字段。这是避免引擎盖下的吗?是否存在避免这种情况的代码设计模式或习惯用法,但仍然具有合理的可读性并且不会过多地牺牲代码的紧凑性?

虽然我在join的上下文中提到了这个问题,但我对在Matlab联接的所有变体中避免表复制的策略感兴趣。

我将描述一个示例,说明Table1ForeignKey中的每条记录如何使用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: []}]} 创建了实际的连接表,并且需要单独的操作来进行计算。

2 个答案:

答案 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' 

然后,您要对列SomeFieldData进行某种操作。

我认为已经添加了这个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,然后复制左表(由于延迟复制,导致副本引用输入表中的数据),并添加列它是正确的表格。