【问题标题】:MYSQL SQL (self) join?MYSQL SQL(自)加入?
【发布时间】:2011-04-21 22:15:51
【问题描述】:

使用此示例数据集:

CREATE TABLE test. test2 (id VARCHAR(7), AA INT, BBB INT, CCC VARCHAR (12));
INSERT INTO test.test2 (id, AA, BBB,CCC) VALUES ( 'A123', 45, 123, '2011-03' );
INSERT INTO test.test2 (id, AA, BBB,CCC) VALUES ( 'A120', 52, 120, '2011-03' );
INSERT INTO test.test2 (id, AA, BBB,CCC) VALUES ( 'A133', 63, 133, '2011-03' );
INSERT INTO test.test2 (id, AA, BBB,CCC) VALUES ( 'D123', 34, 123, '2011-04' );
INSERT INTO test.test2 (id, AA, BBB,CCC) VALUES ( 'D120' ,32, 120, '2011-04' );
INSERT INTO test.test2 (id, AA, BBB,CCC) VALUES ( 'D140', 12, 140, '2011-04' ); 

我正在寻找有 3 列的表格。

Col A "Id" order as Desc from original.

Col B "Id2" 作为 col A 中的上一行或下一行 ID,其中 CCC 相同。

Id,  Id2  CCC
A120 A123 '2011-03'
A123 A133 '2011-03'
A133      '2011-03'
D120 D123 '2011-04'
D123 D140 '2011-04'
D140      '2011-04'

  Id,  Id2  CCC
A120      '2011-03'
A123 A120 '2011-03'
A133 A123 '2011-03'
D120      '2011-04'
D123 D120 '2011-04'
D140 D123 '2011-04'

   Id,  Id2  CCC
   A123 A120 '2011-03'
   A133 A123 '2011-03'
   D123 D120 '2011-04'
   D140 D123 '2011-04'

我可以在连接表中添加一个自动增量列,然后向上或向下使用 1、2、3 行吗?然后 id2 将基于此自动增量行?

【问题讨论】:

    标签: mysql view self-join


    【解决方案1】:
    SELECT test.id, child.id, test.CCC
    FROM test
    LEFT JOIN test AS child ON ((test.CCC = child.CCC) and (test.id < child.id))
    

    接近:

    +------+------+---------+
    | id   | id   | CCC     |
    +------+------+---------+
    | A120 | A123 | 2011-03 |
    | A120 | A133 | 2011-03 |
    | A123 | A133 | 2011-03 |
    | A133 | NULL | 2011-03 |
    | D120 | D123 | 2011-04 |
    | D120 | D140 | 2011-04 |
    | D123 | D140 | 2011-04 |
    | D140 | NULL | 2011-04 |
    +------+------+---------+
    

    【讨论】:

    • 他不想那样,确切地说。只有连续的“对”。
    • 我知道,所以我说“接近”
    【解决方案2】:

    在 Marc 的基础上运作:

    SELECT test.id, child.id, test.CCC
    FROM test
      LEFT JOIN test AS child
        ON (test.CCC = child.CCC)
          AND (test.id < child.id)
    WHERE NOT EXISTS
      ( SELECT 1
        FROM test AS middle
        WHERE (test.CCC = middle.CCC)
          AND (test.id < middle.id)
          AND (middle.id < child.id)
      )
      OR child.id IS NULL
    ORDER BY test.id
    

    这可能对更复杂的查询有所帮助:

    CREATE VIEW testWithRowId AS
      ( SELECT test.id
             , COUNT(test.id) AS rownum
             , test.CCC
        FROM test
          JOIN test AS child
            ON (test.CCC = child.CCC)
              AND (test.id >= child.id)
        GROUP BY test.CCC
               , test.id 
      )
    

    然后使用它:

    SELECT t1.id
         , t2.id AS idShifted
         , t1.CCC
    FROM testWithRowId t1
      LEFT JOIN testWithRowId t2
        ON (t2.CCC = t1.CCC) 
          AND (t2.rownum = t1.rownum + 1)   ---- replace this 1 with 2 or 3, etc
    ORDER BY t1.CCC                         ---- for a shift 2 or shift 3, etc
           , t1.rownum
    

    【讨论】:

    • child.id IS NULL 可以删除而不会造成伤害,或者我需要喝杯咖啡吗?
    • @ypercube,Thnks.... 如果我想向上/向下移动 2 行,那么如何更改代码?
    • @user428862:我的回答不容易改变。
    • 我可以在连接表中添加一个自动增量列,然后向上或向下使用 1、2、3 行吗? “(test.id
    【解决方案3】:
    Select T.Id, NextTest.NextId As Id2, T.CCC
    From Test2 As T
        Left Join   (
                    Select T1.Id, Min( T2.Id ) As NextId
                    From Test2 As T1
                        Left Join Test2 As T2
                            On T2.CCC = T1.CCC
                                And T2.Id > T1.Id
                    Group By T1.Id
                    ) As NextTest
                On NextTest.Id = T.Id
    Order By T.Id       
    

    这应该完全返回您在第一组所需输出中的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2013-05-18
      相关资源
      最近更新 更多