为简单起见:有这3张桌子
my_tickets
+-----------+---------+
| ticket_id | user_id |
+-----------+---------+
| 186 | 2 |
| 187 | 2 |
| 188 | 2 |
| 253 | 33 |
| 254 | 33 |
| 256 | 33 |
| 261 | 33 |
| 262 | 33 |
| 263 | 33 |
| 1573 | 7 |
| 1597 | 7 |
| 1748 | 7 |
+-----------+---------+
my_users
+----+---------+
| id | name |
+----+---------+
| 2 | user_2 |
| 7 | user_7 |
| 33 | user_33 |
+----+---------+
my_data
+----+-----------+------------+
| id | ticket_id | data |
+----+-----------+------------+
| 1 | 186 | data_186_1 |
| 2 | 186 | data_186_2 |
| 3 | 187 | data_187_1 |
| 4 | 253 | data_253_1 |
| 5 | 253 | data_253_2 |
| 6 | 253 | data_253_3 |
| 7 | 254 | data_254_1 |
+----+-----------+------------+
我需要什么:在加入表后获取 3 张票的数据(对象,如数据,而不是行),并且仅适用于 user_id=33。我将使用它进行分页。
Desired output
+-----------------------+---------------------+----------------+---------------+
| my_tickets__ticket_id | my_tickets__user_id | my_users__name | my_data__data |
+-----------------------+---------------------+----------------+---------------+
| 253 | 33 | user_33 | data_253_1 |
| 253 | 33 | user_33 | data_253_2 |
| 253 | 33 | user_33 | data_253_3 |
| 254 | 33 | user_33 | data_254_1 |
| 256 | 33 | user_33 | NULL |
+-----------------------+---------------------+----------------+---------------+
请阅读这篇文章-https://dncrews.com/limit-and-offset-can-work-with-join-f03327fa2ad3
步骤:
Step 1: JOIN
my_tickets.user_id <=> my_users.id
my_tickets.ticket_id <=> my_data.ticket_id)
+-----------------------+---------------------+----------------+---------------+
| my_tickets__ticket_id | my_tickets__user_id | my_users__name | my_data__data |
+-----------------------+---------------------+----------------+---------------+
| 186 | 2 | user_2 | data_186_1 |
| 186 | 2 | user_2 | data_186_2 |
| 187 | 2 | user_2 | data_187_1 |
| 188 | 2 | user_2 | NULL |
| 1573 | 7 | user_7 | NULL |
| 1597 | 7 | user_7 | NULL |
| 1748 | 7 | user_7 | NULL |
| 253 | 33 | user_33 | data_253_1 |
| 253 | 33 | user_33 | data_253_2 |
| 253 | 33 | user_33 | data_253_3 |
| 254 | 33 | user_33 | data_254_1 |
| 256 | 33 | user_33 | NULL |
| 261 | 33 | user_33 | NULL |
| 262 | 33 | user_33 | NULL |
| 263 | 33 | user_33 | NULL |
+-----------------------+---------------------+----------------+---------------+
Step 2: WHERE (my_tickets.user_id = 33)
+-----------------------+---------------------+----------------+---------------+
| my_tickets__ticket_id | my_tickets__user_id | my_users__name | my_data__data |
+-----------------------+---------------------+----------------+---------------+
| 253 | 33 | user_33 | data_253_1 |
| 253 | 33 | user_33 | data_253_2 |
| 253 | 33 | user_33 | data_253_3 |
| 254 | 33 | user_33 | data_254_1 |
| 256 | 33 | user_33 | NULL |
| 261 | 33 | user_33 | NULL |
| 262 | 33 | user_33 | NULL |
| 263 | 33 | user_33 | NULL |
+-----------------------+---------------------+----------------+---------------+
Step 3: LIMIT (limit the result to 3 tickets (object kind))
+-----------------------+---------------------+----------------+---------------+
| my_tickets__ticket_id | my_tickets__user_id | my_users__name | my_data__data |
+-----------------------+---------------------+----------------+---------------+
| 253 | 33 | user_33 | data_253_1 |
| 253 | 33 | user_33 | data_253_2 |
| 253 | 33 | user_33 | data_253_3 |
| 254 | 33 | user_33 | data_254_1 |
| 256 | 33 | user_33 | NULL |
+-----------------------+---------------------+----------------+---------------+
我尝试了什么:
Query
我希望这个查询在表连接后输出 3 个结果(如第 3 步)并且仅针对 user_id=33,但输出为空
SELECT * FROM (
SELECT
my_tickets.ticket_id AS my_tickets__ticket_id, my_tickets.user_id AS my_tickets__user_id,
my_users.name AS my_users__name, my_data.data AS my_data__data
FROM my_tickets
LEFT JOIN my_users ON my_tickets.user_id=my_users.id
LEFT JOIN my_data ON my_tickets.ticket_id=my_data.ticket_id
WHERE my_tickets.user_id = 33
) as t1
WHERE
t1.my_tickets__ticket_id IN (
SELECT * FROM (
SELECT ticket_id FROM my_tickets LIMIT 3 OFFSET 0
) as t2
)
OUTPUT: Empty table
更新: 回答柠檬的陈述:我出于某种原因使用子查询使事情过于复杂。我需要使用 LIMIT OFFSET 来对内容进行分页。 MySQL 正在对返回的行数应用 LIMIT,另一方面我需要对类对象数据应用 LIMIT。为什么像数据这样的对象? => 我更新了初始问题中的表格以反映这一点(添加了 my_data 表格) 基于这篇文章 - https://dncrews.com/limit-and-offset-can-work-with-join-f03327fa2ad3
你似乎把事情复杂化了。你可以在没有子查询的情况下做到这一点:
SELECT t.ticket_id,
t.user_id,
u.name
FROM mytickets t
INNER JOIN myusers u ON t.user_id = u.id
WHERE user_id = 33
LIMIT 3
这保持正确的结果,因为以下按给定顺序激活:
FROM
条款WHERE
条款SELECT
条款LIMIT
条款在这里你可以得到一个彻底的讨论关于子句之间的执行顺序,或者你可以继续官方文档.
此外,请注意输出不是确定性的,因为您不知道数据在数据库中的存储顺序。确定性地检索三行的唯一方法是使用
ORDER BY
子句,能够在行之间强加顺序并打破潜在的联系。
输出:
ticket_id | user_id | 姓名 |
---|---|---|
253 | 33 | user_33 |
254 | 33 | user_33 |
256 | 33 | user_33 |
在这里查看演示.
更新:如果我想将类对象数据限制在指定数量怎么办?
不要使用
LIMIT
,因为它带来了不必要的复杂性,并且变得非常难以处理。
DENSE_RANK
排名窗口函数的输出应用过滤。它将为您的对象行的每个记录分配一个标识符,您可以对其应用过滤。
举个例子:
WITH cte AS (
SELECT t.ticket_id,
t.user_id,
u.name,
DENSE_RANK() OVER(ORDER BY user_id) AS rn
FROM mytickets t
INNER JOIN myusers u ON t.user_id = u.id
)
SELECT *
FROM cte
WHERE rn <= 3
此查询将允许您从最后三个 user_id 值中选择所有记录,而不仅仅是最后三个记录。
首先获得不同的用户和票限制为 3 然后加入
select s.*,md.*,mu.name from
(select distinct user_id,ticket_id from my_tickets mt where user_id = 33 limit 3) s
left join my_data md on md.ticket_id = s.ticket_id
join my_users mu on mu.id = s.user_id