2014-10-04 58 views
0

我有一個查詢連接到表(具有朋友用戶的用戶),我想限制第二個連接表到組的前n行。 我堆棧讀到這裏的幾個線程,這篇文章: http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/將連接限制結果連接到表而不用子查詢

我想知道:是否有任何變化不使用子查詢

這裏有一個數據集例如:

+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 
| id | created_at | updated_at | deleted_at | status | username  | mail    | password | recovery_password | pin | 
+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 
| 1 | 1412441692 |  NULL |  NULL | enabled | first.first  | [email protected]  | 111111 | NULL    | 1111 | 
| 2 | 1412441692 |  NULL |  NULL | enabled | second.second | [email protected] | 222222 | NULL    | 2222 | 
| 3 | 1412441692 |  NULL |  NULL | disabled | third.third  | [email protected]  | 333333 | NULL    | 3333 | 
| 4 | 1412441692 |  NULL |  NULL | enabled | fourth.fourth | [email protected] | 444444 | NULL    | 4444 | 
| 5 | 1412441692 |  NULL |  NULL | disabled | fifth.fifth  | [email protected]  | 555555 | NULL    | 5555 | 
| 6 | 1412441692 |  NULL |  NULL | enabled | sixth.sixth  | [email protected]  | 666666 | NULL    | 6666 | 
| 7 | 1412441692 |  NULL |  NULL | disabled | seventh.seventh | [email protected] | 777777 | NULL    | 7777 | 
+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 

+-----+--------+---------+-----+--------+------------+-----------+ 
| id1 | otype1 | atype | id2 | otype2 | pushed_at | popped_at | 
+-----+--------+---------+-----+--------+------------+-----------+ 
| 1 | user | friends | 2 | user | 1412441692 |  NULL | 
| 1 | user | friends | 3 | user | 1412441692 |  NULL | 
| 2 | user | friends | 1 | user | 1412441692 |  NULL | 
| 2 | user | friends | 6 | user | 1412441692 |  NULL | 
| 4 | user | friends | 3 | user | 1412441692 |  NULL | 
| 6 | user | friends | 2 | user | 1412441692 |  NULL | 
| 6 | user | friends | 7 | user | 1412441692 |  NULL | 
+-----+--------+---------+-----+--------+------------+-----------+ 

這裏是我現在使用的查詢。

SELECT `t1`.`id` AS `id1`, t2.* FROM `User` AS `t1`, `user` AS `t2`, `association` AS `a` WHERE (t1.id = a.id1) AND (t2.id = a.id2) AND (a.otype1 = "user") AND (a.otype2 = "user") AND (a.atype = "friends") 

+-----+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 
| id1 | id | created_at | updated_at | deleted_at | status | username  | mail    | password | recovery_password | pin | 
+-----+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 
| 1 | 2 | 1412441692 |  NULL |  NULL | enabled | second.second | [email protected] | 222222 | NULL    | 2222 | 
| 1 | 3 | 1412441692 |  NULL |  NULL | disabled | third.third  | [email protected]  | 333333 | NULL    | 3333 | 
| 2 | 1 | 1412441692 |  NULL |  NULL | enabled | first.first  | [email protected]  | 111111 | NULL    | 1111 | 
| 2 | 6 | 1412441692 |  NULL |  NULL | enabled | sixth.sixth  | [email protected]  | 666666 | NULL    | 6666 | 
| 4 | 3 | 1412441692 |  NULL |  NULL | disabled | third.third  | [email protected]  | 333333 | NULL    | 3333 | 
| 6 | 2 | 1412441692 |  NULL |  NULL | enabled | second.second | [email protected] | 222222 | NULL    | 2222 | 
| 6 | 7 | 1412441692 |  NULL |  NULL | disabled | seventh.seventh | [email protected] | 777777 | NULL    | 7777 | 
+-----+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 

但我想獲得:

+-----+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 
| id1 | id | created_at | updated_at | deleted_at | status | username  | mail    | password | recovery_password | pin | 
+-----+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 
| 1 | 2 | 1412441692 |  NULL |  NULL | enabled | second.second | [email protected] | 222222 | NULL    | 2222 | 
| 2 | 1 | 1412441692 |  NULL |  NULL | enabled | first.first  | [email protected]  | 111111 | NULL    | 1111 | 
| 4 | 3 | 1412441692 |  NULL |  NULL | disabled | third.third  | [email protected]  | 333333 | NULL    | 3333 | 
| 6 | 2 | 1412441692 |  NULL |  NULL | enabled | second.second | [email protected] | 222222 | NULL    | 2222 | 
+-----+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+ 

回答

1

是的,你可以使用變量。不過,首先你應該寫你的查詢更是這樣的:

SELECT u1.id AS id1, u2.* 
FROM association a JOIN 
    User u1 
    on u1.id = a.id1 and a.otype1 = 'user' JOIN 
    `user` u2 
    ON u2.id = a.id2 and a.otype2 = 'user' 
WHERE a.atype = 'friends' 

的使用注意事項(1)明確join語法; (2)字符串常量的單引號; (3)表名稱縮寫的別名; (4)使用最少的反引號(這只是使查詢難以閱讀。

SELECT uu.* 
FROM (SELECT u1.id AS id1, u2.*, 
      (@rn := if(@id1 = id1, @rn + 1, 
         if(@id1 := id1, 1, 1) 
         ) 
      ) rn 
     FROM association a JOIN 
      User u1 
      on u1.id = a.id1 and a.otype1 = 'user' JOIN 
      `user` u2 
      ON u2.id = a.id2 and a.otype2 = 'user' CROSS JOIN 
      (SELECT @id1 := 0, @rn := 0) vars 
     WHERE a.atype = 'friends' 
     ORDER BY u1.id 
    ) uu 
WHERE rn = 1; 
+0

EHI戈登,第一關的感謝。我試圖找出你的查詢。1)不是那些子查詢? 2)第一個選擇是否有編號行的技巧? 3)請您再解釋一下第一個選擇和交叉連接選擇嗎?我非常感謝你幫助我 – 2014-10-04 21:06:05

+0

有一個很大的子查詢,並用'id'命令結果。然後使用變量枚舉每個「id」的行。 「交叉連接」和後續的子查詢只是在查詢中定義變量。 – 2014-10-05 13:44:52