Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 获取数据的最新版本,并将其设置为版本0,并删除每天的所有其他记录_Perl_Bash_Sqlite_Greatest N Per Group - Fatal编程技术网

Perl 获取数据的最新版本,并将其设置为版本0,并删除每天的所有其他记录

Perl 获取数据的最新版本,并将其设置为版本0,并删除每天的所有其他记录,perl,bash,sqlite,greatest-n-per-group,Perl,Bash,Sqlite,Greatest N Per Group,表: 输入 日期数据,版本标识符 20130909 dsfcat 0,7 20130909 dosdfg 1,7 20130909 dsdfog 0,8 20130909 dsdfog 3,8 20130910 afsdfds 0,8 130910 afsdfds 2、8 输出 日期数据,版本标识符 20130909 dosdfg 0,7 20130909 dsdfog 0,8 20130910 afsdfds 0,8 我有一个表,用于存储每天的多个版本的数据 每个数据不需要有所有的版本。主键是

表:

输入 日期数据,版本标识符 20130909 dsfcat 0,7 20130909 dosdfg 1,7 20130909 dsdfog 0,8 20130909 dsdfog 3,8 20130910 afsdfds 0,8 130910 afsdfds 2、8 输出 日期数据,版本标识符 20130909 dosdfg 0,7 20130909 dsdfog 0,8 20130910 afsdfds 0,8
  • 我有一个表,用于存储每天的多个版本的数据
  • 每个数据不需要有所有的版本。主键是日期、标识符、版本
  • 目标:对于每个日期的每个标识符(可以由多行组成),将max version设置为0并删除所有其他记录

    我试图避免使用联接。我可以用perl、bash脚本来补充它


    编辑:1。也许我可以删除所有不是最高版本的值,然后将eights version设置为0。

    下面的代码是否符合您的要求

    Output Date Data, version identifier 20130909 dosdfg 0 , 7 20130909 dsdfog 0 , 8 20130910 afsdfds 0, 8
    在内部
    foreach
    循环内。但是,我还没有对此进行测试,所以我不确定它是否有效。

    这完全可以通过SQL完成:

    my $query = "DELETE FROM $table_name WHERE date = $date AND identifier = $identifier AND data != $data";
    
    这样做的目的是删除其密钥字段与包含每个标识符/日期的最高版本号的记录关联的密钥列表不匹配的所有记录,然后更新其余记录,使其版本号为0

    其他建议:

  • 我不知道这个数据库会有多大,但您可能希望添加一个“已处理”字段,用于指示给定记录是否已通过每日修剪过程;否则,查询所通过的数据集将始终包含已处理的记录,这些记录将随着时间的推移而增长
  • 如果将当前主键定义更改为唯一索引,然后添加单个主键字段(如自动递增的数字),则查询无需在
    DELETE
    和sub-
    SELECT
    中将所有主键字段串联在一起

  • 这能解决你的问题吗<代码>awk'$3==0'文件?(不带标题)如果需要标题
    awk'NR==1 | |$3==0”文件
    它存储在数据库中……如果需要特定日期,您将如何修改它?谢谢
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    open my $fh, "data.in" or die "$!";
    
    my %table;
    while (<$fh>) {
        chomp;
        my ($date, $data, $version, $identifier) = split;
    
        if (not defined $table{$date}{$identifier}{version}
                or $table{$date}{$identifier}{version} < $version) {
            $table{$date}{$identifier}{version} = $version;
            $table{$date}{$identifier}{data} = $data;
        }
    }
    
    close $fh;
    
    foreach my $date (sort keys %table) {
        foreach my $identifier (sort keys $table{$date}) {
            my $data = $table{$date}{$identifier}{data};
            $table{$date}{$identifier}{version} = 0;
            my $version = $table{$date}{$identifier}{version};
            print "$date\t$data\t$version\t$identifier\n";
        }
    }
    
    my $query = "DELETE FROM $table_name WHERE date = $date AND identifier = $identifier AND data != $data";
    
    sqlite> SELECT * FROM tbl;
    20130909|dsfcat|0|7
    20130909|dosdfg|1|7
    20130909|dsdfog|0|8
    20130909|dsdfog|3|8
    20130910|afsdfds|0|8
    20130910|afsdfds|2|8
    
    sqlite> DELETE FROM
       ...>   tbl
       ...> WHERE
       ...>   Date||':'||identifier||':'||version NOT IN (
       ...>     SELECT
       ...>       Date||':'||identifier||':'||version
       ...>     FROM
       ...>       tbl
       ...>     GROUP BY
       ...>       identifier,Date
       ...>     HAVING
       ...>       version=MAX(version)
       ...>   );
    sqlite> UPDATE tbl SET version=0;
    
    sqlite> SELECT * FROM tbl;
    20130909|dosdfg|0|7
    20130909|dsdfog|0|8
    20130910|afsdfds|0|8