1

我有两个类似的 sql 查询,它们只有不同的 where 子句过滤器来提取适当的管理员名称(point_of_contact、admin)。我需要生成结合两个过滤查询结果的结果,但我不确定如何解决这个问题。除了联系人和管理员之外,这些列是相同的。我需要 admin 和 point_of_contact 位于不同的列中。有联系点或管理员,但不能同时保留一个空值。我尝试过递归 sql 和 case 语句,但我遇到了一些麻烦。我将查询分为以下两个简单查询。(DB2 - 不确定版本)

SELECT  
                DP.DIM_PROJECT_ID, 
                DP.PROJECT_NAME, 
                DP.POINT_OF_CONTACT,
                DP.FIELD,
                DD.YEAR

            FROM FACT_Table FAT 
            RIGHT OUTER JOIN DIM_A AS DA on FAT.DIM_A_ID = DA.DIM_A_ID 
            INNER JOIN DIM_P DP on DA.DIM_P_ID = DP.DIM_P_ID
            INNER JOIN BRIDGE_USER BUP on BUP.BRIDGE_ID = DP.DIM_P_ID
            INNER JOIN DIM_DATE DD on DD.DATE_KEY = DA.A_START_DATE_ID
        WHERE DA.AWARD_CATEGORY <> 'N/A'   
        AND DD.YEAR = '2013'
        and (
                SELECT count(BUP_INNER.ADMIN_FLAG) FROM BRIDGE_USER BUP_INNER 
                INNER JOIN DIM_P DP_INNER on BUP_INNER.DIM_P_ID = DP_INNER.DIM_P_ID
                WHERE DP_INNER.DIM_P_ID = DP.DIM_P_ID
                    AND BUP_INNER.ADMIN_FLAG = 'Y'
                ) = 0
        GROUP BY DA.AWARD_TYPE_NAME, DA.AWARD_CATEGORY, DP.PROJECT_NAME, DP.POINT_OF_CONTACT, DD.YEAR

SELECT distinct
    DP.DIM_PROJECT_ID,
    DU.NAME_LAST CONCAT ', ' CONCAT t1.NAME_FIRST AS ADMIN,
    DP.PROJECT_NAME,
    DP.PROJECT_TITLE,
    DD.YEAR,
    DP.FIELD
FROM FACT_Table as FAT
INNER JOIN DIM_P DP ON FAT.DIM_P_ID = DP.DIM_P_ID
INNER JOIN BRIDGE_USER BUP on DP.DIM_P_ID = BUP.DIM_P_ID
INNER JOIN DIM_USER DU ON FAT.DIM_USER_ID = DU.DIM_USER_ID
INNER JOIN DIM_DATE DD on DD.DATE_KEY = DA.A_START_DATE_ID
INNER JOIN DIM_A DA ON FAT.DIM_A_ID = DA.DIM_A_ID

WHERE BUP.ADMIN_FLAG = 'Y'
and DD.YEAR = '2013'
and DA.AWARD_CATEGORY <> 'NA'

)
GROUP BY
    DP.DIM_P_ID,
    DU.NAME_LAST CONCAT ', ' CONCAT DU.NAME_FIRST,
    DP.PROJECT_NAME,
    DP.TITLE,
    DD.YEAR,
    DP.FIELD
4

2 回答 2

1

在不使用它们的地方设置为空的额外列

SELECT distinct 
         DP.DIM_PROJECT_ID, 
         DP.PROJECT_NAME,
         DP.PROJECT_TITLE,
         null as admin, 
         DP.POINT_OF_CONTACT,
         DP.FIELD,
         DD.YEAR

  FROM   FACT_Table   FAT 
  RIGHT OUTER 
  JOIN   DIM_A        DA    on FAT.DIM_A_ID = DA.DIM_A_ID 
  JOIN   DIM_P        DP    on DA.DIM_P_ID = DP.DIM_P_ID
  JOIN   BRIDGE_USER  BUP   on BUP.BRIDGE_ID = DP.DIM_P_ID
            JOIN DIM_DATE     DD    on DD.DATE_KEY = DA.A_START_DATE_ID
  WHERE DA.AWARD_CATEGORY <> 'N/A'   
    and DD.YEAR = '2013'
    and NOT EXISTS (
                     SELECT *
                       FROM BRIDGE_USER  BUP_INNER 
                       JOIN DIM_P        DP_INNER
                          on DP_INNER.DIM_P_ID = BUP_INNER.DIM_P_ID
                       WHERE DP_INNER.DIM_P_ID = DP.DIM_P_ID
                         AND BUP_INNER.ADMIN_FLAG = 'Y'
                   ) 
UNION ALL

SELECT distinct
    DP.DIM_PROJECT_ID,
    DP.PROJECT_NAME,
    DP.PROJECT_TITLE,
    DU.NAME_LAST CONCAT ', ' CONCAT t1.NAME_FIRST AS ADMIN,
    null as POINT_OF_CONTACT,
    DD.YEAR,
    DP.FIELD
  FROM FACT_Table as FAT
  JOIN DIM_P         DP   ON  FAT.DIM_P_ID = DP.DIM_P_ID
  JOIN BRIDGE_USER   BUP  on  BUP.DIM_P_ID = DP.DIM_P_ID
                          and BUP.ADMIN_FLAG = 'Y'
  JOIN DIM_USER      DU   ON  FAT.DIM_USER_ID = DU.DIM_USER_ID
  JOIN DIM_DATE      DD   on  DD.DATE_KEY = DA.A_START_DATE_ID
                          and DD.YEAR = '2013'
  JOIN DIM_A         DA   ON  DA.DIM_A_ID = FAT.DIM_A_ID
                          and DA.AWARD_CATEGORY <> 'NA'

NOT EXISTS 应该更有效,因为它会在找到满足子查询的一行时返回答案。另一方面,COUNT(*) 将继续搜索满足子查询的所有行。

我省略了您的 GROUP BY 子句,因为我不明白您要对它们做什么,因为没有涉及聚合函数。

于 2013-09-03T23:27:49.830 回答
1

如果两个查询都给出了您想要的数据(??),那么为什么不先有一个名称列,然后再有一个名称类型列。

在第一个查询中,将 DP.POINT_OF_CONTACT 作为 specialName。向此查询“Point of Contact”添加一列作为 nameType。

在第二个查询中,将“as ADMIN”更改为 as specialName。在查询“Admin”中添加一列作为 nameType。

您可能需要对第一个查询中的 project_title 做一些事情,但是您应该能够将这两组结果合并。然后在稍后处理结果的查询中,您将能够在 nameType 列上进行操作。

这是你要去的方向吗?如果不是,那么可能需要问题中的更多细节。最好的尼克。

于 2013-09-03T19:26:06.023 回答