2011-04-21 67 views
1

使用这个样本数据集:MYSQL SQL(self)join?

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从原始描述的“Id”顺序。作为上一行或下一行的上一行Id(其中CCC是相同的),列B中的“Id2”作为上一行或下一行。

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' 

OR

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

我能添加一个autocrement山口到连接表,然后用1,2,3行向上或向下?那么id2会基于这个自动调整行?

回答

1

工作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 
+0

'child.id IS NULL'可以被移除而不会造成伤害,或者我需要一些咖啡? – 2011-04-21 22:44:27

+0

@ypercube,Thnks ....如果我想向上/向下移动2行,那么如何更改代码? – Merlin 2011-04-21 22:51:50

+0

@ user428862:我的回答不是一个简单的改变。 – 2011-04-21 23:18:43

3
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 | 
+------+------+---------+ 
+0

他不希望出现这种情况,究竟。只有连续的“双”。 – 2011-04-21 22:31:20

+0

我知道,所以我说“得到关闭” – 2011-04-21 22:33:08

1
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  

这应返回正是你在你的第一套所需的输出。