我有一个查询连接到表(用户和朋友用户),我想将第二个连接表限制为组的前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 | first@first.com | 111111 | NULL | 1111 |
| 2 | 1412441692 | NULL | NULL | enabled | second.second | second@second.com | 222222 | NULL | 2222 |
| 3 | 1412441692 | NULL | NULL | disabled | third.third | third@third.com | 333333 | NULL | 3333 |
| 4 | 1412441692 | NULL | NULL | enabled | fourth.fourth | fourth@fourth.com | 444444 | NULL | 4444 |
| 5 | 1412441692 | NULL | NULL | disabled | fifth.fifth | fifth@fifth.com | 555555 | NULL | 5555 |
| 6 | 1412441692 | NULL | NULL | enabled | sixth.sixth | sixth@sixth.com | 666666 | NULL | 6666 |
| 7 | 1412441692 | NULL | NULL | disabled | seventh.seventh | seventh@seventh.com | 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 | second@second.com | 222222 | NULL | 2222 |
| 1 | 3 | 1412441692 | NULL | NULL | disabled | third.third | third@third.com | 333333 | NULL | 3333 |
| 2 | 1 | 1412441692 | NULL | NULL | enabled | first.first | first@first.com | 111111 | NULL | 1111 |
| 2 | 6 | 1412441692 | NULL | NULL | enabled | sixth.sixth | sixth@sixth.com | 666666 | NULL | 6666 |
| 4 | 3 | 1412441692 | NULL | NULL | disabled | third.third | third@third.com | 333333 | NULL | 3333 |
| 6 | 2 | 1412441692 | NULL | NULL | enabled | second.second | second@second.com | 222222 | NULL | 2222 |
| 6 | 7 | 1412441692 | NULL | NULL | disabled | seventh.seventh | seventh@seventh.com | 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 | second@second.com | 222222 | NULL | 2222 |
| 2 | 1 | 1412441692 | NULL | NULL | enabled | first.first | first@first.com | 111111 | NULL | 1111 |
| 4 | 3 | 1412441692 | NULL | NULL | disabled | third.third | third@third.com | 333333 | NULL | 3333 |
| 6 | 2 | 1412441692 | NULL | NULL | enabled | second.second | second@second.com | 222222 | NULL | 2222 |
+-----+----+------------+------------+------------+----------+-----------------+---------------------+----------+-------------------+------+
答案 0 :(得分: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;