postgresql数据库left join将主表中的数据查询出多条的解决办法

今天遇到了一个比较纳闷的bug

 1  select
 2         tbd.item_id as item_ID,
 3         tbi.item_code||'-'||tbi.item_name as item_name,
 4         tb.budget_code ||'-'|| tb.budget_name as budget_name,
 5         tbd.org_code ||'-'|| tot.org_name as org_code,
 6         ROUND(tbi.TOTAL_amount,2) AS TOTAL_amount,
 7         tbi.item_type,
 8         tbi.ITEM_DEFINE,
 9         tbd.exe_type,
10         tbd.BUDGET_DETAIL_ID,
11         tbd.product_code,
12         case when DECLARE_CARD_NUM='' then 0
13         when DECLARE_CARD_NUM is null then 0
14         else round(to_number(DECLARE_CARD_NUM,'9999999999999999999'),0) end
15         AS DECLARE_CARD_NUM,
16         case when ACTUAL_CARD_NUM='' then 0
17         when ACTUAL_CARD_NUM is null then 0
18         else round(to_number(ACTUAL_CARD_NUM,'9999999999999999999'),0) end
19         AS ACTUAL_CARD_NUM,
20         case when DECLARE_CREDITS_NUM='' then 0
21         when DECLARE_CREDITS_NUM is null then 0
22         else round(to_number(DECLARE_CREDITS_NUM,'9999999999999999999'),0) end
23         AS DECLARE_CREDITS_NUM,
24         case when ACTUAL_CREDITS_NUM='' then 0
25         when ACTUAL_CREDITS_NUM is null then 0
26         else round(to_number(ACTUAL_CREDITS_NUM,'9999999999999999999'),0) end
27         AS ACTUAL_CREDITS_NUM,
28         ROUND(tbd.DECLARE_TOTAL_AMOUNT,2) as DECLARE_TOTAL_AMOUNT ,
29         ROUND(tbd.ACTUAL_TOTAL_AMOUNT,2) as ACTUAL_TOTAL_AMOUNT ,
30         to_char(tbd.item_startdate, 'yyyy-MM-dd') item_startdate,
31         to_char(tbd.item_enddate, 'yyyy-MM-dd') item_enddate,
32         to_char(tbd.INSERT_TIME, 'yyyy-mm-dd hh24:mi:ss') INSERT_TIME,
33         tbd.detail_code,
34         TPT.operate_type,
35         to_char(tbd.update_time,'yyyy-mm-dd hh24:mi:ss'),
36         tbd.update_oper,
37         tbd.actual_price,
38         TPT.ID,
39         to_char(TPT.INSERT_TIME, 'yyyy-mm-dd hh24:mi:ss')  OPERATE_TIME,
40         TPT.INSERT_OPER
41         from T_BUDGET_DETAIL tbd join T_BUDGET_ITEM tbi on tbd.item_id = tbi.item_id
42         left join T_BUDGET tb on tb.budget_id = tbi.budget_id
43         LEFT JOIN T_PROJECT_TRACE TPT ON TPT.BUDGET_DETAIL_ID = tbd.BUDGET_DETAIL_ID
44         left join t_organization tot on tbd.org_code = tot.org_code
45         where 1=1
46         <if test="budgetCode !='' and budgetCode != null">
47             and tb.budget_code =#{budgetCode}
48         </if>
49         <if test="itemCode !='' and itemCode !=null  ">
50             and tbi.item_code =#{itemCode,jdbcType=VARCHAR}
51         </if>
52         <if test="orgCode !='' and orgCode !=null">
53             and tbd.org_code like #{orgCode,jdbcType=VARCHAR}
54         </if>
55         <if test="exeType !='' and exeType != null ">
56             and tbd.exe_type =#{exeType,jdbcType=VARCHAR}
57         </if>
58         <if test=" operateType !='' and operateType != null ">
59             and TPT.operate_type =#{operateType,jdbcType=VARCHAR}
60         </if>
61         <if test="exeTime !='' and exeTime != null  ">
62             and to_char(TPT.INSERT_TIME,'yyyy-MM-dd')  &gt;=  #{exeTime}
63         </if>
64         <if test=" doneTime !='' and doneTime != null">
65             and to_char(TPT.INSERT_TIME,'yyyy-MM-dd') &lt;=  #{doneTime}
66         </if>
67         and tbd.status = '02'
68         and TPT.status is null
69      
70         order by OPERATE_TIME desc

这条sql在运行的时候,主表

T_BUDGET_DETAIL  和t_budget_item两张表中明明只有一条数据,但是查询出来的结果却有两条数据。
出现这个问题的原因:
t_organization表又将t_project_trace表当成了主表。
t_project_trace表中有两条记录,这样无形中将
T_BUDGET_DETAIL  和t_budget_item表中的一条数据进行了重复 显示。
解决办法:(控制t_project_trace表只显示一条数据)
 select
        tbd.item_id as item_ID,
        tbi.item_code||'-'||tbi.item_name as item_name,
        tb.budget_code ||'-'|| tb.budget_name as budget_name,
        tbd.org_code ||'-'|| tot.org_name as org_code,
        ROUND(tbi.TOTAL_amount,2) AS TOTAL_amount,
        tbi.item_type,
        tbi.ITEM_DEFINE,
        tbd.exe_type,
        tbd.BUDGET_DETAIL_ID,
        tbd.product_code,
        case when DECLARE_CARD_NUM='' then 0
        when DECLARE_CARD_NUM is null then 0
        else round(to_number(DECLARE_CARD_NUM,'9999999999999999999'),0) end
        AS DECLARE_CARD_NUM,
        case when ACTUAL_CARD_NUM='' then 0
        when ACTUAL_CARD_NUM is null then 0
        else round(to_number(ACTUAL_CARD_NUM,'9999999999999999999'),0) end
        AS ACTUAL_CARD_NUM,
        case when DECLARE_CREDITS_NUM='' then 0
        when DECLARE_CREDITS_NUM is null then 0
        else round(to_number(DECLARE_CREDITS_NUM,'9999999999999999999'),0) end
        AS DECLARE_CREDITS_NUM,
        case when ACTUAL_CREDITS_NUM='' then 0
        when ACTUAL_CREDITS_NUM is null then 0
        else round(to_number(ACTUAL_CREDITS_NUM,'9999999999999999999'),0) end
        AS ACTUAL_CREDITS_NUM,
        ROUND(tbd.DECLARE_TOTAL_AMOUNT,2) as DECLARE_TOTAL_AMOUNT ,
        ROUND(tbd.ACTUAL_TOTAL_AMOUNT,2) as ACTUAL_TOTAL_AMOUNT ,
        to_char(tbd.item_startdate, 'yyyy-MM-dd') item_startdate,
        to_char(tbd.item_enddate, 'yyyy-MM-dd') item_enddate,
        to_char(tbd.INSERT_TIME, 'yyyy-mm-dd hh24:mi:ss') INSERT_TIME,
        tbd.detail_code,
        TPT.operate_type,
        to_char(tbd.update_time,'yyyy-mm-dd hh24:mi:ss'),
        tbd.update_oper,
        tbd.actual_price,
        TPT.ID,
        to_char(TPT.INSERT_TIME, 'yyyy-mm-dd hh24:mi:ss')  OPERATE_TIME,
        TPT.INSERT_OPER
        from T_BUDGET_DETAIL tbd join T_BUDGET_ITEM tbi on tbd.item_id = tbi.item_id
        left join T_BUDGET tb on tb.budget_id = tbi.budget_id
        LEFT JOIN T_PROJECT_TRACE TPT ON TPT.BUDGET_DETAIL_ID = tbd.BUDGET_DETAIL_ID
        left join t_organization tot on tbd.org_code = tot.org_code
        where 1=1
        <if test="budgetCode !='' and budgetCode != null">
            and tb.budget_code =#{budgetCode}
        </if>
        <if test="itemCode !='' and itemCode !=null  ">
            and tbi.item_code =#{itemCode,jdbcType=VARCHAR}
        </if>
        <if test="orgCode !='' and orgCode !=null">
            and tbd.org_code like #{orgCode,jdbcType=VARCHAR}
        </if>
        <if test="exeType !='' and exeType != null ">
            and tbd.exe_type =#{exeType,jdbcType=VARCHAR}
        </if>
        <if test=" operateType !='' and operateType != null ">
            and TPT.operate_type =#{operateType,jdbcType=VARCHAR}
        </if>
        <if test="exeTime !='' and exeTime != null  ">
            and to_char(TPT.INSERT_TIME,'yyyy-MM-dd')  &gt;=  #{exeTime}
        </if>
        <if test=" doneTime !='' and doneTime != null">
            and to_char(TPT.INSERT_TIME,'yyyy-MM-dd') &lt;=  #{doneTime}
        </if>
        and tbd.status = '02'
        and TPT.status is null
        and TPT.update_time=(select max(update_time) from t_project_trace where BUDGET_DETAIL_ID=TPT.BUDGET_DETAIL_ID )
        order by OPERATE_TIME desc
原文地址:https://www.cnblogs.com/dongyaotou/p/12991398.html