英文:
How to get data from table where query condition related to query selected records
问题
以下是您要翻译的部分:
Context
I have the table "user_numbers" with the following records:
id | user_id | number |
---|---|---|
1 | 3 | 123 |
2 | 3 | 666 |
3 | 4 | 123 |
4 | 5 | 666 |
5 | 6 | 555 |
6 | 7 | 123 |
7 | 7 | 444 |
8 | 8 | 444 |
I want to build query that find all user numbers and all user numbers that users have.
For example above I want to get user's number 3, 4, 5, 7 and 8 if i will select by the next condition user_id = 3.
For user 3 i got numbers:
- 123
- 666
For number 123 i got users:
- 4
- 7
For number 666 i got usres:
- 5
User 7 has numbers:
- 123
- 444
For number 444 i got users:
- 8
In result i got all user numbers linked by number:
id | user_id | number |
---|---|---|
1 | 3 | 123 |
2 | 3 | 666 |
3 | 4 | 123 |
4 | 5 | 666 |
6 | 7 | 123 |
7 | 7 | 444 |
8 | 8 | 444 |
I create the next query:
WITH RECURSIVE founded_user_numbers AS (
select
un.id,
un.user_id,
un.number
from p2p_market.user_numbers un
where un.user_id = 1
UNION
select
iun.id,
iun.user_id,
iun.number
from p2p_market.user_numbers iun, founded_user_numbers fun
where iun.number = fun.number and iun.id != fun.id and iun.user_id != fun.user_id
)
SELECT * FROM founded_user_numbers;
It works fine. Buy if i change UNION to UNION ALL or add order by i get infinity query.
Can anyone help me to write right condition to get required data.
英文:
Context
I have the table "user_numbers" with the following records:
id | user_id | number |
---|---|---|
1 | 3 | 123 |
2 | 3 | 666 |
3 | 4 | 123 |
4 | 5 | 666 |
5 | 6 | 555 |
6 | 7 | 123 |
7 | 7 | 444 |
8 | 8 | 444 |
I want to build query that find all user numbers and all user numbers that users have.
For example above I want to get user's number 3, 4, 5, 7 and 8 if i will select by the next condition user_id = 3.
For user 3 i got numbers:
- 123
- 666
For number 123 i got users:
- 4
- 7
For number 666 i got usres:
- 5
User 7 has numbers:
- 123
- 444
For number 444 i got users:
- 8
In result i got all user numbers linked by number:
id | user_id | number |
---|---|---|
1 | 3 | 123 |
2 | 3 | 666 |
3 | 4 | 123 |
4 | 5 | 666 |
6 | 7 | 123 |
7 | 7 | 444 |
8 | 8 | 444 |
I create the next query:
WITH RECURSIVE founded_user_numbers AS (
select
un.id,
un.user_id,
un.number
from p2p_market.user_numbers un
where un.user_id = 1
UNION
select
iun.id,
iun.user_id,
iun.number
from p2p_market.user_numbers iun, founded_user_numbers fun
where iun.number = fun.number and iun.id != fun.id and iun.user_id != fun.user_id
)
SELECT * FROM founded_user_numbers;
It works fine. Buy if i change UNION to UNION ALL or add order by i get infinity query.
Can anyone help me to write right condition to get required data.
答案1
得分: 1
根据您的数据集和结果,看起来您希望根据用户ID查找所有具有至少一个相同数字的用户。我认为这里不需要递归。以下是一种使用布尔窗口函数来执行的方法:
select user_id
from (
select n.*,
bool_or(user_id = 3) over(partition by number) number_has_user_id_3
from user_numbers n
) n
group by user_id
having bool_or(number_has_user_id_3)
order by user_id
number_has_user_id_3
检查用户 3
是否具有与当前行上的数字相同的数字 - 然后我们可以使用它来筛选用户。
您还可以使用相关子查询(尽管这可能是一种效率较低的方法):
select user_id
from user_numbers n
where exists (select 1 from user_numbers n1 where n1.number = n.number and n1.user_id = 3)
group by user_id
order by user_id
user_id |
---|
3 |
4 |
5 |
英文:
From your dataset and results, it looks like, given a user id, you want all users that have a least one number in common. I don't see the need for recursion here. Here is one way to do it with boolean window functions:
select user_id
from (
select n.*,
bool_or(user_id = 3) over(partition by number) number_has_user_id_3
from user_numbers n
) n
group by user_id
having bool_or(number_has_user_id_3)
order by user_id
number_has_user_id_3
checks if user 3
has the same number as the one on the current row - which we can then use to filter users.
You could also use a correlated subquery (although that might be a less efficient approach):
select user_id
from user_numbers n
where exists (select 1 from user_numbers n1 where n1.number = n.number and n1.user_id = 3)
group by user_id
order by user_id
user_id |
---|
3 |
4 |
5 |
答案2
得分: 1
我不太确定这是否是您正在寻找的,但我认为您可以通过简单地使用自连接来实现这一点。
select distinct test.t1_user_id from
(select
t1.id as t1_id
,t1.user_id as t1_user_id
,t1.number as t1_number
,t2.user_id as t2_user_id
,t2.number as t2_number
from test t1
left join test t2
on t1.number = t2.number
and t1.user_id <> t2.user_id
where t2.user_id is not null) test
英文:
I'm not really sure if this is what you are looking for, but I think you can achieve this by simply using a self-join.
select distinct test.t1_user_id from
(select
t1.id as t1_id
,t1.user_id as t1_user_id
,t1.number as t1_number
,t2.user_id as t2_user_id
,t2.number as t2_number
from test t1
left join test t2
on t1.number = t2.number
and t1.user_id <> t2.user_id
where t2.user_id is not null) test
答案3
得分: 1
select distinct un.user_id from cte c
,user_numbers un
where un.number in (c.number)
英文:
with cte as
(
select *
from user_numbers
where user_id = 3
)
select distinct un.user_id from cte c
,user_numbers un
where un.number in (c.number)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论