【问题标题】:How to join two tables based on some condition in sql?如何根据sql中的某些条件连接两个表?
【发布时间】:2020-12-02 06:01:53
【问题描述】:

我需要帮助来连接两个表以获得输出。我告诉你场景。你能帮帮我吗?

例子:

我有一个 sql 查询: 查询:

SELECT * 
FROM (
  SELECT schemaname ,objectname,usename,
         HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'select') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS sel,
         HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'insert') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS ins,
         HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'update') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS upd,
         HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'delete') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS del,
         HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'references') AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS ref 
  FROM (
     SELECT schemaname, 't' AS obj_type, tablename AS objectname, schemaname + '.' + tablename AS fullobj 
     FROM pg_tables 
     WHERE schemaname not in ('pg_internal') 
     UNION 
     SELECT schemaname, 'v' AS obj_type, viewname AS objectname, schemaname + '.' + viewname AS fullobj 
     FROM pg_views 
     WHERE schemaname not in ('pg_internal')
  ) AS objs,
  (SELECT * FROM pg_user) AS usrs ORDER BY fullobj
) 
WHERE (sel = true or ins = true or upd = true or del = true or ref = true) 
   and schemaname='medaff' 
   and usename not in ('rdsdb','clustersa','prdrscl01master') 
   and objectname in RES;

上面的查询给出了一些输出:

Table 1

schemaname  objectname   usename           sel  ins  upd  del  ref
medaff      dmn_category medaff_dev_admin  True True True True True
medaff      dmn_category emea_dev_admin    True True True True True
medaff      dmn_category cdeadmin          True True True True True

我有其他表有一些记录:

Table 2:

application_name  tablename
smart_source      dmn_category

如何连接这两个表以在最终输出中获取应用程序名称:

application_name schemaname  objectname   usename           sel  ins  upd  del  ref  
smart_source     medaff      dmn_category medaff_dev_admin  True True True True True
smart_source     medaff      dmn_category emea_dev_admin    True True True True True
smart_source     medaff      dmn_category cdeadmin          True True True True True

【问题讨论】:

  • 您需要第二个表中的字段与第一个表中的字段匹配。第一个表是否包含应用程序名称或表名称?表 1 中的 ObjectName 是否与表 2 中的表名相同?
  • 您确定这是 Amazon Redshift 吗?我在问,因为我认为他们使用的是标准串联运算符||,而您在这里使用的是+schemaname + '.' + tablename AS fullobj,我只从 SQL Server 知道。
  • 是的,它正在亚马逊红移中运行

标签: sql join amazon-redshift


【解决方案1】:

我认为这里的重点是您想将一个复杂的查询结果与另一个表连接起来?您可以通过以下方式实现:

  1. 使用WITH tbl AS (.....)然后加入tbl上的另一个表(查询结果)。
  2. 为您的第一个结果创建一个VIEW,然后将另一个表与该视图连接起来。

【讨论】:

    【解决方案2】:

    当您想表示 2 个表时,您可以使用 inner join on 但为此您需要在每个表中都有一些共同点。 例如:

    select t.name, o.code from FirstTable t inner join OtherTable o on t.code = o.code
    

    【讨论】:

    • 错误:Redshift 表不支持指定的类型或函数(每个 INFO 消息一个)。收到此错误。
    • @Shivam 我刚刚在我的电脑上试了一下,效果很好。表必须有匹配的东西,否则内部连接不起作用
    • 好的.. 但我没有得到我需要保留第一个查询的地方?
    • 我正在尝试这个:
    【解决方案3】:

    您的查询看起来不错。不过,UNION 应该是 UNION ALL,并且

    ) AS objs,
    (SELECT * FROM pg_user) AS usrs
    

    应该是

    ) AS objs
    CROSS JOIN pg_user AS usrs
    

    ORDER BY fullobj
    

    是多余的,因为允许 DBMS 忽略子查询中的ORDER BY。 (如果您希望对结果进行排序,请在查询末尾添加 ORDER BY fullobj。)

    但无论如何,你似乎想要的只是加入 table2:

    ) AS objs
    CROSS JOIN pg_user AS usrs
    INNER JOIN table2 ON table2.tablename = objs.objectname
    

    完整的查询:

    SELECT * FROM 
    (
      SELECT
        table2.application_name,
        objs.schemaname,
        objs.objectname,
        usrs.usename,
        HAS_TABLE_PRIVILEGE(usrs.usename, objs.fullobj, 'select') AND has_schema_privilege(usrs.usename, objs.schemaname, 'usage') AS sel,
        HAS_TABLE_PRIVILEGE(usrs.usename, objs.fullobj, 'insert') AND has_schema_privilege(usrs.usename, objs.schemaname, 'usage') AS ins,
        HAS_TABLE_PRIVILEGE(usrs.usename, objs.fullobj, 'update') AND has_schema_privilege(usrs.usename, objs.schemaname, 'usage')  AS upd,
        HAS_TABLE_PRIVILEGE(usrs.usename, objs.fullobj, 'delete') AND has_schema_privilege(usrs.usename, objs.schemaname, 'usage')  AS del,
        HAS_TABLE_PRIVILEGE(usrs.usename, objs.fullobj, 'references') AND has_schema_privilege(usrs.usename, objs.schemaname, 'usage') AS ref
      FROM
      (
        SELECT 
          schemaname, 
          't' AS obj_type, 
          tablename AS objectname, 
          schemaname + '.' + tablename AS fullobj
        FROM pg_tables 
        WHERE schemaname not in ('pg_internal') 
        UNION ALL
        SELECT 
          schemaname, 
          'v' AS obj_type, 
          viewname AS objectname, 
          schemaname + '.' + viewname AS fullobj 
        FROM pg_views 
        WHERE schemaname not in ('pg_internal')
      ) AS objs
      CROSS JOIN pg_user AS usrs
      INNER JOIN table2 ON table2.tablename = objs.objectname
    )
    WHERE (sel = true or ins = true or upd = true or del = true or ref = true)
      and schemaname = 'medaff' 
      and usename not in ('rdsdb', 'clustersa', 'prdrscl01master')
    ORDER BY schemaname, objectname, application_name, usename;
    

    【讨论】:

    • 你能给我完整的join查询吗?
    • 您实际上应该能够自己执行此操作。无论如何,我已将查询添加到我的答案中。
    • 错误:Redshift 表不支持指定的类型或函数(每个 INFO 消息一个)
    • 啊,好吧。我查看了错误,看来您无法在 Redshift 中加入 pg_views 和您自己的表。至少我是这样理解的:stackoverflow.com/questions/57326426/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 2016-11-18
    • 2021-11-10
    • 1970-01-01
    相关资源
    最近更新 更多