代码之家  ›  专栏  ›  技术社区  ›  Barzo

在mysql表中查找id不唯一的漏洞

  •  1
  • Barzo  · 技术社区  · 10 年前

    MySql表定义为:

    CREATE TABLE tbl_misure_30m (
      m_rcd_id          INT NOT NULL AUTO_INCREMENT ,
      m_fon_id          INT UNSIGNED,
      m_timestamp       TIMESTAMP,
      m_fon_rcd_id      INT UNSIGNED,
      m_fon_Leq         FLOAT(4,2),
      m_fon_LsMax       FLOAT(4,2),
      m_Leq_state       INT,
      m_LsMax_state     INT,
      m_fon_mem_block   INT,
    
      INDEX fon_key (m_fon_id),
      FOREIGN KEY (m_fon_id) REFERENCES tbl_users(fon_id)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
    
      PRIMARY KEY ( m_rcd_id )
    
    ) ENGINE = InnoDB;
    

    哪里:

    • m_rcd_id 是自动递增的索引
    • m_fon_id 是“用户”id,我有几个m_fon_rcd_id
    • m_fon_rcd_id 是相对于每个m_fon_id的记录id(因此这些不是唯一的)。

    遗憾的是,数据库设计无法更改。

    现在,我需要验证列m_fon_rcd_id( 对于每个m_fon_id )不包含孔(在这种情况下,我需要知道范围)。

    我希望得到的结果集如下:|gap_starts_at|gap_ends_at|m_fon_id|

    我找到了 this answer 但各种id是唯一的,这是理所当然的:

    SELECT (t1.m_fon_rcd_id + 1) as gap_starts_at, 
           (SELECT MIN(t3.m_fon_rcd_id) -1 FROM tbl_misure_30m t3 WHERE t3.m_fon_rcd_id > t1.m_fon_rcd_id) as gap_ends_at
    FROM tbl_misure_30m t1
    WHERE NOT EXISTS (SELECT t2.m_fon_rcd_id FROM tbl_misure_30m t2 WHERE t2.m_fon_rcd_id = t1.m_fon_rcd_id + 1 )
    HAVING gap_ends_at IS NOT NULL
    

    有什么建议吗?

    提前感谢!

    1 回复  |  直到 7 年前
        1
  •  1
  •   Gordon Linoff    10 年前

    我会通过获取下一个值来实现这一点。然后做一些算术运算:

    select m_fon_rcd_id + 1 as gapstart, next_m_fon_rcd_id - 1 as gap_ends,
           (next_m_fon_rcd_id - m_fon_rcd_id - 1) as gap_length
    from (select m_fon_rcd_id,
                 (select m2.m_fon_rcd_id
                  from tbl_misure_30m m2
                  where m2.m_fon_rcd_id > m.m_fon_rcd_id
                  order by m_fon_rcd_id
                  limit 1
                 ) as next_m_fon_rcd_id
          from tbl_misure_30m m
         ) m
    where next_m_fon_rcd_id > m_fon_rcd_id + 1;
    

    编辑:

    如果您想在 m_fon_id ,您可以将其添加到查询的各个部分:

    select m_fon_id, m_fon_rcd_id + 1 as gapstart, next_m_fon_rcd_id - 1 as gap_ends,
           (next_m_fon_rcd_id - m_fon_rcd_id - 1) as gap_length
    from (select m_fon_rcd_id,
                 (select m2.m_fon_rcd_id
                  from tbl_misure_30m m2
                  where m2.m_fon_id = m.m_fon_id and
                        m2.m_fon_rcd_id > m.m_fon_rcd_id
                  order by m_fon_rcd_id
                  limit 1
                 ) as next_m_fon_rcd_id
          from tbl_misure_30m m
         ) m
    where next_m_fon_rcd_id > m_fon_rcd_id + 1;