如何从表中获取与查询选择的记录相关的查询条件的数据

huangapple go评论64阅读模式
英文:

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

fiddle

英文:

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

fiddle

答案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

SQL Fiddle

英文:

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 &lt;&gt; t2.user_id

  where t2.user_id is not null) test

SQL Fiddle

答案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)

huangapple
  • 本文由 发表于 2023年6月19日 23:42:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76508169.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定