Performance 在Qlikview中,可以执行;严格字段“;连接

Performance 在Qlikview中,可以执行;严格字段“;连接,performance,concatenation,qlikview,Performance,Concatenation,Qlikview,到现在为止,我已经使用qlikview好几年了,我几乎每天都会遇到一个简单的问题,就是需要将表与不同的字段连接起来,而我只需要其中的一些字段 例如,假设我在单独的QVD上有以下表格 表1: 表2: 我只需要用字段_1、字段_2和字段_3创建一个最终表格,但如果我这样做了 我得到一个错误,表2中不存在字段_2。我可以将null()作为字段_2,当我处理少量表时,我知道字段不存在,但当我在500多个QVD上迭代时,其中一些有字段,一些没有字段,我需要一种方法来确定这一点 现在我有两种方法来解决

到现在为止,我已经使用qlikview好几年了,我几乎每天都会遇到一个简单的问题,就是需要将表与不同的字段连接起来,而我只需要其中的一些字段

例如,假设我在单独的QVD上有以下表格

表1:

表2:

我只需要用字段_1、字段_2和字段_3创建一个最终表格,但如果我这样做了

我得到一个错误,表2中不存在字段_2。我可以将null()作为字段_2,当我处理少量表时,我知道字段不存在,但当我在500多个QVD上迭代时,其中一些有字段,一些没有字段,我需要一种方法来确定这一点

现在我有两种方法来解决这个问题:

  • 我首先用*加载qvd,并使用FIELDNUMBER查看该字段是否存在,然后将该字段放入变量中,以便在加载时使用
  • 例如:

  • 我正在创建一个空的starter表,其中字段设置为null,并使用load*连接到该表,以便生成缺少的字段(利用“使用null生成缺少的字段”)
  • 例如:

    这在性能上是相当糟糕的,因为我正在将整个文件加载到内存中,而我只对几列感兴趣,然后需要稍后删除它们

    是否有一种方法可以使连接只接受第一个表中已经存在的列,以null完成缺少的列,但自动排除所有其他非必需字段

    在使用*加载之前,我尝试使用前面的加载,但当其中一个字段不在qvd上时,加载失败。有什么想法吗


    注:我知道我描述的方法解决了这个问题,但我正在寻找性能和速度方面更好的解决方案。

    在Qlik中连接两个表时,不需要字段匹配。您甚至可以用完全不同的字段连接两个表,Qlik不会抱怨。Qlik将只为缺少的字段添加
    null

    查看下面的脚本-我们有两个表
    Table1
    Table2

    • 表1
      的字段:
      字段1
      字段2
      字段3
    • 表2
      的字段:
      字段3
      字段4
      字段5
    当从
    表1
    加载所有字段并从
    表2
    仅连接
    字段3
    时,结果将是:

    field1
    field2
    为源于表2的行填充
    null

    Table1:
    Load * Inline [
      field1, field2, field3
      1     , 2     , 3     
      4     , 5     , 6
    ];
    
    Table2:
    Load * Inline [
      field3, field4, field5
      1     , 2     , 3
      4     , 5     , 6
    ];
    
    NoConcatenate
    
    
    ConcatenatedTable:
    Load
      field1,
      field2,
      field3
    Resident
      Table1
    ;
    
    Concatenate
    
    Load
      field3
    Resident
      Table2
    ;
    
    Drop Tables Table1, Table2;
    

    这是一种不同的方法,我没有足够大的数据集来测试它的性能,但至少解决了在脚本中有显式字段名的问题,这可能是一个需要维护的噩梦

    首先使用交叉表加载所有文件,以解构结构:

    for each file in FileList('<folder>\<files>*')
    
       RawTable:
       CrossTable(Field, Data, 2)
       LOAD FileName() as FileName,
             RowNo() as RowId,
             *
       FROM
        [$(file)]
        (txt, utf8, no labels, embedded labels, delimiter is ',');
    
    next file;
    
    然后使用文件中每个已知字段的不同名称创建支持表:

    FieldTable:
    LOAD
        Distinct Field as KnownField 
    Resident RawTable;
    
    最后,魔术开始了,在这里,您可以一个字段一个字段地左键将它们连接到DataTable:

    LET NumFields = NoOfRows('FieldTable');
    
    FOR i = 0 to $(NumFields) - 1
        LET vField = Peek('KnownField', $(i), 'FieldTable');
    
        TRACE $(vField);
    
        Left Join(DataTable)
        LOAD
            FileName,
            RowId,
            Data as $(vField)
        Resident RawTable
        WHERE Field = '$(vField)';  
    NEXT;
    
    最后,进行一些清理:

    DROP TABLE RawTable;
    DROP TABLE FieldTable;
    

    如果只想保留字段的一个子集,则可以在创建字段表时进行筛选。

    要获得更高性能的解决方案,可以先获取每个qvd的元数据以获取其包含的字段,然后在此基础上设置qvd迭代逻辑

    以下是提供qvd文件字段名的主脚本:

    LOAD
        "FieldName"
    FROM [some.qvd]
    (XmlSimple, table is [QvdTableHeader/Fields/QvdFieldHeader]);
    

    感谢您的回复,当我不知道加载的数据集的字段名并且希望将它们与可能的字段名列表相匹配时,我使用类似的逻辑;但由于qlikview中的FOR行的性能极低,我宁愿在可能的时候避免它们。我给出的例子已经奏效了,我只是想看看是否有一种更有效的方法来为anwser执行itthx,也许我没有正确地表达自己:我知道强制连接会生成空字段(我在第二个例子中使用它)。我的问题是,当我有500个qvd和f1、f2、f3、f4等,并且只想连接[f1 f2 f3],但有些表没有f2,我无法预先知道哪些表是f2,我要么预加载每个qvd以检查字段是否存在,要么强制将整个文件连接到一个空表。这两种解决方案我都不喜欢,因为我最终在内存中加载了更多我真正需要的数据,并降低了性能。我想过这样做,但这与加载文件并使用fieldnumber进行检查是一样的,这意味着我最终从磁盘读取了两次相同的文件。我知道我正试图通过使用怪异/神秘的代码来获得0.5%的性能提升,但我不得不问
    LOAD
        "FieldName"
    FROM [some.qvd]
    (XmlSimple, table is [QvdTableHeader/Fields/QvdFieldHeader]);