【问题标题】:Correctly do an Outer Join in the same table在同一张表中正确执行外部联接
【发布时间】:2016-06-15 15:42:41
【问题描述】:

我有以下查询

SELECT DISTINCT P.CUSTUM_ID, P.STATUS, M.DATE_RATE, PP.PRICE_USR, PP.DISC
FROM MBR_INFO AS M
INNER JOIN PARENT_INFO AS P
  on M.CUSTUM_ID = P.CUSTUM_ID
INNER JOIN PRICE_PARENT PP
  on P.CUSTUM_ID = PP.CUSTUM_ID
WHERE M.DATE_RATE > (getDate())
  and P.USER_FLAG = 'Y'
order by M.DATE_RATE;

产生以下输出

|   CUSTUM_ID   |   STATUS  |   DATE_RATE   |   STATU   |   ORIG_P  |   PRICE_U |   DISC
---------------------------------------------------------------------------------------------
|   12345678    |   USER    |   2015-05-19  |   NULL    |   0.00    |   2990.00 |   0.00
|   12345678    |   NONUSR  |   2015-05-19  |   NULL    |   0.00    |   5980.00 |   0.00
|   56789012    |   USER    |   2015-08-06  |   NULL    |   0.00    |   0.00    |   0.00
|   56789012    |   NONUSR  |   2015-08-06  |   NULL    |   0.00    |   400.00  |   0.00
|   35789651    |   USER    |   2015-12-23  |   NULL    |   0.00    |   1990.00 |   0.00
|   35789651    |   NONUSR  |   2015-12-23  |   NULL    |   0.00    |   3980.00 |   0.00
|   25879460    |   USER    |   2016-01-01  |   NULL    |   0.00    |   2000.00 |   0.00
|   25879460    |   NONUSR  |   2016-01-11  |   NULL    |   0.00    |   4000.00 |   0.00

如您所见,我们有两个价格,用户和非用户。我想更改我的查询,使其在同一行中同时显示用户和非用户价格,从而删除用户状态,现在将其与用户和公众的价格一起显示,类似这样,

|   CUSTUM_ID   |   DATE_RATE   |   STATU   |   ORIG_P  |   PRICEU  |   PRICENU |   DISC
---------------------------------------------------------------------------------------------
|   12345678    |   2015-05-19  |   NULL    |   0.00    |   2990.00 |   5980.00 |   0.00
|   56789012    |   2015-08-06  |   NULL    |   0.00    |   0.00    |   400.00  |   0.00
|   35789651    |   2015-12-23  |   NULL    |   0.00    |   1990.00 |   3980.00 |   0.00
|   25879460    |   2016-01-01  |   NULL    |   0.00    |   2000.00 |   4000.00 |   0.00

我一直在阅读,最好的建议是使用FULL OUTER JOIN,但到目前为止,我得到的输入与使用内连接相同。如何更改查询以显示我需要的数据?

【问题讨论】:

    标签: mysql join inner-join outer-join


    【解决方案1】:

    您可以使用条件聚合

    SELECT P.CUSTUM_ID, M.DATE_RATE, PP.DISC,
           MAX(CASE WHEN P.STATUS = 'USER' THEN PP.PRICE_USR END) AS PRICEU,
           MAX(CASE WHEN P.STATUS = 'NONUSR' THEN PP.PRICE_USR END) AS PRICENU 
    FROM MBR_INFO AS M
    INNER JOIN PARENT_INFO AS P
      on M.CUSTUM_ID = P.CUSTUM_ID
    INNER JOIN PRICE_PARENT PP
      on P.CUSTUM_ID = PP.CUSTUM_ID
    WHERE M.DATE_RATE > (getDate())
      and P.USER_FLAG = 'Y'
    GROUP BY P.CUSTUM_ID, M.DATE, PP.DISC
    ORDER BY M.DATE_RATE;
    

    如果每个组有单独的 M.DATE 值,那么您可以从 GROUP BY 子句中删除 M.DATE 字段,并使用聚合函数(如 MIN(M.DATE))将该字段包含在 SELECT 中。

    【讨论】:

    • M.DATE_RATEM.DATE?
    • 像手套一样!我可以问你一个问题,为什么我们必须做GROUP BY?我问是因为没有它查询失败
    • @Tavo 每个CUSTUM_ID 有一组,每组包含两条记录:一条用于P.STATUS = 'USER',另一条用于P.STATUS = 'NONUSR'
    【解决方案2】:

    你可以自己加入表格。

    这只是向您展示如何将两行转换为一行的部分。您仍然需要其他表。

     SELECT P_USER.CUSTUM_ID, 
            P_USER.STATUS,    -- I know is user
            P_NOUSER.STATUS   -- I know is not user
     FROM PARENT_INFO as P_USER
     JOIN PARENT_INFO as P_NOUSER
       ON P_USER.CUSTUM_ID = P_NOUSER.CUSTUM_ID
    WHERE
         P_USER.STATUS = 'USER'
     AND P_NOUSER.STATUS = 'NONUSR'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-11
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-27
      • 2012-02-01
      • 2021-01-25
      相关资源
      最近更新 更多