【问题标题】:alias some columns names as one field in oracle's join select query在 oracle 的连接选择查询中将某些列名称别名为一个字段
【发布时间】:2023-03-10 14:13:01
【问题描述】:

我们正在开发类似社交网站的东西。我有任务要做 “跟我来”功能。我们网站的对象是用户、团队、公司、渠道和群组(请不要问为什么会有群组和团队——这对我来说也很复杂,但是团队与用户的才能有关)

用户、团队、频道、公司和群组都有自己的表格。

我有一个查询,可以让我找到所有像这样的追随者领导

select
  --fo.leader_id,
  --fo.leader_type,
  us.name as user_name,
  co.name as company_name,
  ch.title as channel_name,
  gr.name as group_name,
  tt.name as team_name
from
  follow_up fo
left join users us
  on (fo.leader_id = us.id and fo.leader_type = 'user')
left join companies co
  on (fo.leader_id = co.user_id and fo.leader_type = 'company')
left join channels ch
  on (fo.leader_id = ch.id and fo.leader_type = 'channel')
left join groups gr
  on (fo.leader_id = gr.id and fo.leader_type = 'group')
left join talent_teams tt
  on (fo.leader_id = tt.id and fo.leader_type = 'team')
where
  follower_id = 83

我需要获取所有字段,例如:

  • 用户名,
  • 公司名称,
  • 频道名称,
  • 组名,
  • 团队名称

作为 SELECT 产品中的一个字段。 我试图给它们起一个别名,但甲骨文给它编号。 请帮忙:)

【问题讨论】:

    标签: sql oracle select join alias


    【解决方案1】:

    我开始思考并想出了这个解决方案:

    它比 Jeffrey Kemp 的解决方案慢吗?

    select
      fo.leader_id,
      fo.leader_type,
    
      case
        when us.subdomain is not null then us.subdomain
        when us2.subdomain is not null then us2.subdomain
        --when co.name is not null then co.name
        when ch.service_url is not null then ch.service_url
        when gr.id is not null then to_char(gr.id)
        when tt.subdomain is not null then tt.subdomain
        else 'nothing!'
        end
        as leader_url,
    
      case
        when us.name is not null then us.name
        when co.name is not null then co.name
        when ch.title is not null then ch.title
        when gr.name is not null then gr.name
        when tt.name is not null then tt.name
        else 'nothing!'
        end
        as leader_names,
    
        case
        when us.img_avatar_path is not null then us.img_avatar_path
        when us2.img_avatar_path is not null then us2.img_avatar_path
        --when us.img_avatar_path is not null and fo.leader_id = co.user_id and fo.leader_type = 'company' then us.img_avatar_path
        when ch.default_img is not null then ch.default_img
        when gr.img_avatar_path is not null then gr.img_avatar_path
        when tt.img_avatar_path is not null then tt.img_avatar_path
        else 'nothing!'
        end
        as img_avatar_path,
    
        case
        when us.img_avatar_x is not null then us.img_avatar_x
        when us2.img_avatar_x is not null then us2.img_avatar_x
        when  ch.default_img_x is not null then ch.default_img_x
        when gr.img_avatar_x is not null then gr.img_avatar_x
        when tt.img_avatar_x is not null then tt.img_avatar_x
        else 0
        end
        as img_avatar_x,
    
        case
        when us.img_avatar_y is not null then us.img_avatar_y
        when us2.img_avatar_y is not null then us2.img_avatar_y
        when  ch.default_img_y is not null then ch.default_img_y
        when gr.img_avatar_y is not null then gr.img_avatar_y
        when tt.img_avatar_y is not null then tt.img_avatar_y
        else 0
        end
        as img_avatar_y
    
    from
      follow_up fo
      left join users us
      on (fo.leader_id = us.id and fo.leader_type = 'user')
      left join companies co
      on (fo.leader_id = co.user_id and fo.leader_type = 'company')
        left join users us2
        on (co.user_id = us2.id)
      left join channels ch
      on (fo.leader_id = ch.id and fo.leader_type = 'channel')
      left join groups gr
      on (fo.leader_id = gr.id and fo.leader_type = 'group')
      left join talent_teams tt
      on (fo.leader_id = tt.id and fo.leader_type = 'team')
    where
      follower_id = :follower_id
    

    【讨论】:

    • COALESCE 函数将完全按照您对 CASE 语句所做的工作。
    • 这两个查询返回完全不同的结果,所以我会选择更适合您的应用程序,而不是担心性能(除非您已经知道性能是一个真正的问题)。
    【解决方案2】:

    查询结果集中的列名必须是唯一的。也许您希望给定追随者的每个用户、公司、频道、组和团队都有一行?在这种情况下,我会使用这样的查询:

    select fo.leader_type, us.name
    from follow_up fo
    join users us
      on (fo.leader_id = us.id and fo.leader_type = 'user')
    where follower_id = 83
    UNION ALL
    select fo.leader_type, co.name
    from follow_up fo
    join companies co
      on (fo.leader_id = co.user_id and fo.leader_type = 'company')
    where follower_id = 83
    UNION ALL
    select fo.leader_type, ch.title as name
    from follow_up fo
    join channels ch
      on (fo.leader_id = ch.id and fo.leader_type = 'channel')
    where follower_id = 83
    UNION ALL
    select fo.leader_type, gr.name
    from follow_up fo
    join groups gr
      on (fo.leader_id = gr.id and fo.leader_type = 'group')
    where follower_id = 83
    UNION ALL
    select fo.leader_type, tt.name
    from follow_up fo
    join talent_teams tt
      on (fo.leader_id = tt.id and fo.leader_type = 'team')
    where follower_id = 83
    

    【讨论】:

    • 我选择这个是因为它解决了我的问题,但我也想出了自己的解决方案,请在下方评论。
    【解决方案3】:

    我不确定您为什么需要将它们作为一个字段,因为您不需要在客户端拆分信息吗?无论如何,您可以这样做的一种方法是:

    user_name || '|' || company_name || '|' || channel_name || '|' || group_name || '|' || team_name all_fields
    

    这将为您提供一个名为 all_fields 的管道分隔字段。如果您有来自不同表的多个 user_name 字段,则可以使用相同的方法:

       table1.user_name || '|' || table2.user_name ... all_user_names
    

    然后您可以在客户端拆分字段。

    就个人而言,我会做这样的事情:

        table1.user_name table1_user_name
      , table2.user_name table2_user_name
        ...
    

    换句话说,只需为每个 user_name 使用唯一的列别名。

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 2021-07-27
      • 1970-01-01
      • 2017-10-06
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      相关资源
      最近更新 更多