【问题标题】:sqlite query - add key to records between null records?sqlite 查询 - 向空记录之间的记录添加键?
【发布时间】:2014-01-29 23:19:44
【问题描述】:

我正在查询存储在数据库中的一些系统日志,不幸的是,供应商在创建数据库结构方面的表关系方面做得很差。我通常用于此类事情的报告工具依赖于标准 SQLite 查询(无脚本/编码),我更愿意使用该标准报告工具将这个关于系统中用户操作的报告踢出,以便可以安排和监控它确保它运行。

这些日志列出了用户在系统中执行的操作,我需要将 2 个表绑定在一起以获取他们所做的完整报告。

表 1:供应商很友好地在其中包含了一个键。

Key                     Other_Columns
-------------------------------------
jdoe|20140122|093537    stuff
jdoe3|20140122|093657   stuff
jdoe2|20140122|151644   stuff

表 2:此表中没有键,但它与另一表相关联。

UID     Date        Time       Server    Action
------------------------------------------------
jdoe    1/22/2014   9:35:37
jdoe    1/22/2014   9:35:37    server1   action1
jdoe    1/22/2014   9:35:41    server1   action2
jdoe3   1/22/2014   9:36:57
jdoe3   1/22/2014   9:36:58    server3   action1
jdoe3   1/22/2014   9:37:01    server4   action2
jdoe2   1/22/2014   15:16:44
jdoe2   1/22/2014   15:16:44   server2   action1
jdoe2   1/22/2014   15:16:46   server2   action2
jdoe2   1/22/2014   15:16:49   server2   action3

现在为了让这更有趣,您会注意到表 1 中的 Key 使用时间戳作为其中的一部分。对于 Server 和 Action 为空的用户,时间戳与表 2 中的第一个时间戳相匹配。如果您查询表 2 并按日期排序,然后按时间排序,则用户所做操作的每个日志部分都以时间戳和空白服务器和操作条目开头。我能想到的加入这些的唯一方法是通过使用 UID、日期、时间列以某种方式为表 2 创建一个键,但我需要对空操作/服务器行之间的每一行应用相同的键。这让我很难过。

我想我需要自己查询表 2 以创建下面的临时表,然后将其连接回表 1,但我不知道如何编写一个查询来从表 2 生成下面的输出:

UID      Date         Time       Server     Action     Key
----------------------------------------------------------------------------
jdoe     1/22/2014    9:35:37                          jdoe|20140122|093537
jdoe     1/22/2014    9:35:37    server1    action1    jdoe|20140122|093537
jdoe     1/22/2014    9:35:41    server1    action2    jdoe|20140122|093537
jdoe3    1/22/2014    9:36:57                          jdoe3|20140122|093657
jdoe3    1/22/2014    9:36:58    server3    action1    jdoe3|20140122|093657
jdoe3    1/22/2014    9:37:01    server4    action2    jdoe3|20140122|093657
jdoe2    1/22/2014    15:16:44                         jdoe2|20140122|151644
jdoe2    1/22/2014    15:16:44   server2    action1    jdoe2|20140122|151644
jdoe2    1/22/2014    15:16:46   server2    action2    jdoe2|20140122|151644
jdoe2    1/22/2014    15:16:49   server2    action3    jdoe2|20140122|151644

我不确定这是否可行,但如果可以,我希望有人知道。

想法?

【问题讨论】:

    标签: sql sqlite


    【解决方案1】:

    这可能会做你想做的事:

    select t2.*,
           (select "key"
            from table1 t1
            where t1."key" >= t2.uid || '|' || strftime(date, '%Y%m%d')
            order by t1."key"
            limit 1
           ) as "Key"
    from table2 t2;
    

    它找到第一个大于连接到日期的uid 的键。那应该是你想要的。

    【讨论】:

    • 几乎成功了!我实际上刚刚意识到表 1 并不总是在表 2 中有匹配的记录。表 1 包含有关用户采取的操作的附加信息,但并不是他们所做的一切都会在这个细节上生成日志(我想我知道他们为什么拆分这个现在跨表),如果 t1 中没有匹配,这将导致生成的“密钥”在 t2 中不准确。
    • @user3246693 。 . .您可以添加where 条件,例如t1."key" like t2.uid || '|' || strftime(date, '%Y%m%d') || '%'
    【解决方案2】:

    SQLite 不支持该日期格式。 您必须使用字符串操作来提取日期字段:

    SELECT *,
           Table2.UID || '|' ||
           CASE
           WHEN Table2.Date LIKE '__/__/____' THEN substr(Table2.Date, 7, 4) ||        substr(Table2.Date, 4, 2) ||        substr(Table2.Date, 1, 2)
           WHEN Table2.Date LIKE '_/__/____'  THEN substr(Table2.Date, 6, 4) ||        substr(Table2.Date, 3, 2) || '0' || substr(Table2.Date, 1, 1)
           WHEN Table2.Date LIKE '__/_/____'  THEN substr(Table2.Date, 6, 4) || '0' || substr(Table2.Date, 4, 1) ||        substr(Table2.Date, 1, 2)
           WHEN Table2.Date LIKE '_/_/____'   THEN substr(Table2.Date, 5, 4) || '0' || substr(Table2.Date, 3, 1) || '0' || substr(Table2.Date, 1, 1)
           END || '|' ||
           CASE
           WHEN Table2.Time LIKE '__:__:__' THEN        substr(Table2.time, 1, 2) || substr(Table2.time, 4, 2) || substr(Table2.time, 7, 2)
           WHEN Table2.Time LIKE '_:__:__'  THEN '0' || substr(Table2.time, 1, 1) || substr(Table2.time, 3, 2) || substr(Table2.time, 6, 2)
           END AS T2Key
    FROM Table1
    JOIN Table2 ON Table1.Key = T2Key
    ORDER BY Date,
             Time
    

    【讨论】:

    • 感谢您的发现,日期格式实际上被 Excel 搞砸了。我将一些数据从表格中复制到 MS Excel 中,这样我就可以在此处发布之前清除实际的用户数据。我刚刚意识到 Excel 重新格式化了我的日期。
    猜你喜欢
    • 1970-01-01
    • 2016-09-25
    • 2017-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多