INNER JOIN 与 h2 数据库和 postgresql 数据库的区别

Posted

技术标签:

【中文标题】INNER JOIN 与 h2 数据库和 postgresql 数据库的区别【英文标题】:INNER JOIN differences with h2 database and postgresql database 【发布时间】:2017-10-13 02:13:05 【问题描述】:

因此,我将代码数据库从 h2 更改为 postgresql,并且我注意到在 h2 中使用的 Inner Join 调用在我在 postgresql 中调用时并没有给出相同的结果。我做了研究,经过测试,我发现左连接和其他连接工作得很好,只有内连接给了我不同的结果。那么,要让两个输出 csv 文件匹配,我是否必须更改表的整个结构,或者我忽略了 postgresql 中的类似内容?

   public void doAllWork(int type, Connection conn, Statement st) 

    try 

        if (type == 1) 
            st.execute("DROP TABLE IF EXISTS COMBINEDDATA;"); //USING DISTINCT TO EXCLUDE DUPLICATE RECORDS
            st.execute("ANALYZE");
            st.execute("CREATE TABLE COMBINEDDATA AS \n"
                  + "SELECT DISTINCT E.DATA1, E.DATA2, E.DATA3, E.DATA4, E.DATA5, E.DATA6, \n"
                    + "E.DATA7, E.DATA8, E.DATA9, E.DATA10, E.DATA11, E.DATA12, E.DATA13, E.DATA14, E.DATA15, E.DATA16, E.DATA17, \n"
                    + "E.DATA18, E.DATA19, E.DATA21, E.DATA26, E.DATA27, E.DATA28, E.DATA29, \n"
                    + "E.DATA30, E.DATA31, E.DATA32, E.DATA34, E.DATA35, E.DATA36, E.DATA37, E.DATA38, \n"
                    + " C.CHAIN20, C.CHAIN33, C.CHAIN22, \n "
                    + "D.DAT2, D.DAT3, D.DAT4, D.DAT7, D.DAT11, D.DAT9, D.DAT5, \n "
                    + "E.DATA39,  E.DATA40, E.DATA41 FROM rawData AS E \n"
                    + "RIGHT JOIN CHAINDATA AS C \n"
                    + "ON E.DATA7 = c.CHAIN2\n"
                    + "AND E.DATA11 = c.CHAIN4\n"
                    + "AND E.DATA21 = c.CHAIN10\n"
                    + "AND E.DATA22 = c.CHAIN11\n"
                    + "RIGHT JOIN DATDATA AS D\n"
                    + "ON E.DATA7 = D.DAT18\n"
                    + "AND E.DATA11 = D.DAT21\n"
                    + "AND UCASE(E.DATA6) = UCASE(D.DAT17)\n"
                    + "AND UCASE(E.DATA10) = UCASE(D.DAT20)\n"
                    + "AND UCASE(E.DATA5) = UCASE(D.DAT16)\n"
                    + "AND UCASE(E.DATA9) = UCASE(D.DAT19)\n"
                    + "AND E.DATA20 = D.DAT22");

         else if (type == 2) 
            st.execute("DROP TABLE IF EXISTS COMBINEDDATA2;");
            st.execute("ANALYZE");
            st.execute("CREATE TABLE COMBINEDDATA2 AS \n"
                  + "SELECT DISTINCT E.DATA1, E.DATA2, E.DATA3, E.DATA4, E.DATA5, E.DATA6, \n"
                    + "E.DATA7, E.DATA8, E.DATA9, E.DATA10, E.DATA11, E.DATA12, E.DATA13, E.DATA14, E.DATA15, E.DATA16, E.DATA17, \n"
                    + "E.DATA18, E.DATA19, E.DATA21, E.DATA26, E.DATA27, E.DATA28, E.DATA29, \n"
                    + "E.DATA30, E.DATA31, E.DATA32, E.DATA34, E.DATA35, E.DATA36, E.DATA37, E.DATA38, \n"
                    + " C.CHAIN20, C.CHAIN33, C.CHAIN22, \n "
                    + "D.DAT2, D.DAT3, D.DAT4, D.DAT7, D.DAT11, D.DAT9, D.DAT5, \n "
                    + "E.DATA39,  E.DATA40, E.DATA41 FROM rawData AS E \n"
                    + "LEFT JOIN CHAINDATA AS C \n"
                    + "ON E.DATA7 = c.CHAIN2\n"
                    + "AND E.DATA11 = c.CHAIN4\n"
                    + "AND E.DATA21 = c.CHAIN10\n"
                    + "AND E.DATA22 = c.CHAIN11\n"
                    + "LEFT JOIN DATDATA AS D\n"
                    + "ON E.DATA7 = D.DAT18\n"
                    + "AND E.DATA11 = D.DAT21\n"
                    + "AND UCASE(E.DATA6) = UCASE(D.DAT17)\n"
                    + "AND UCASE(E.DATA10) = UCASE(D.DAT20)\n"
                    + "AND UCASE(E.DATA5) = UCASE(D.DAT16)\n"
                    + "AND UCASE(E.DATA9) = UCASE(D.DAT19)\n"
                    + "AND E.DATA20 = D.DAT22");
        
        System.out.println("here");

        if (type == 1) 
            String dir = System.getProperty("user.dir");
            st.executeUpdate("CALL CSVWRITE('" + dir + "\\OnlyMatching.csv', 'SELECT * FROM COMBINEDDATA','charset=UTF-8');"); //,
         else if (type == 2) 
            String dir = System.getProperty("user.dir");
            st.executeUpdate("CALL CSVWRITE('" + dir + "\\AllNonMatching.csv', 'SELECT * FROM COMBINEDDATA2','charset=UTF-8');");
        

     catch (Exception ex) 
        Logger.getLogger(RyderCombinerGUI.class.getName()).log(Level.SEVERE, null, ex);
    


在上面的 sn-p 中,左连接的第二个循环在 h2 和 postgresql 上的工作方式相同,但内连接循环返回的结果不同。

前) 这是使用 h2 数据库的输出 csv 文件。

这是使用 postgresql 数据库的输出

提前致谢。

【问题讨论】:

【参考方案1】:

假设您在 H2 和 Postgres 中使用相同的基础数据运行相同的符合 ANSI 的查询,您应该得到相同的结果。 INNER JOIN 在任一数据库中的行为都没有任何不同。

但是在您的代码转储中快速搜索ORDER BY 显示您没有在查询中进行任何排序。我注意到 Postgres 巧合地似乎在 data1 列上排序,而 H2 似乎根本没有排序。我建议从未排序集的角度来看,结果集是相同的。

一般来说,如果您希望结果集中有一个 cetain 排序,则需要在生成该数据的查询中使用 ORDER BY。因此,如果您将 ORDER BY data1 添加到两个查询中,我预计 H2 和 Postgres 的结果将相同。

【讨论】:

哦,好的,谢谢,在进一步查看 csv 文件后,它们确实是相同的,只是顺序不同。我对数据库还很陌生,所以我对 ORDER BY 不太了解,但我确信这确实是问题所在。

以上是关于INNER JOIN 与 h2 数据库和 postgresql 数据库的区别的主要内容,如果未能解决你的问题,请参考以下文章

MySQL Using temporary; Using filesort INNER JOIN优化

join on 与inner join 有啥不同呢 ?

inner join 与 left join 之间的区别

Oracle中Inner join和Where的区别

关于SQL数据库中cross join 和inner join用法上的区别?

`pd.concat` 与 `join=='inner'` 不会产生 pandas 数据帧的交集