首页 > 解决方案 > 当给定查询在左连接中有内部查询时如何获取列名和列标签

问题描述

谁能帮我获取实际的列名及其别名ResultSetMetaData

    class MysqlCon {
    public static void main(String args[]) {
        Connection con = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
            Statement stmt = con.createStatement();
            String query = "SELECT \n" + 
                    "  RA_Min_1 AS 'ran Min',\n" + 
                    "  RA_Max_1 AS 'ran Max' \n" + 
                    "FROM\n" + 
                    "  `Masters` m \n" + 
                    "  LEFT JOIN \n" + 
                    "    (SELECT \n" + 
                    "      mr.`Master_ID`,\n" + 
                    "      `RA_Min_1`,\n" + 
                    "      `RA_Max_1` \n" + 
                    "    FROM\n" + 
                    "      `Master_Attribute_Range` mr \n" + 
                    "      INNER JOIN `Masters` m \n" + 
                    "        ON m.`Master_Type_ID` = 3 \n" + 
                    "        AND mr.`Master_ID` = m.`Master_ID`)  mar\n" + 
                    "    ON mar.Master_ID = m.`Master_ID` \n" + 
                    "    AND m.`Master_Type_ID` = 3 \n" + 
                    "ORDER BY RA_min_1 \n" + 
                    "LIMIT 0, 25 ";

            ResultSet rs = stmt.executeQuery(query);

            ResultSetMetaData rsm =rs.getMetaData();
            for (int i = 1; i <= rsm.getColumnCount(); i++) {
                System.out.println(rsm.getColumnLabel(i) + "--" + rsm.getColumnName(i));
            }
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

输出

ran Min--ran Min
ran Max--ran Max

在这里,如果我删除ORDER BY RA_min_1子句,那么它将返回预期的输出:

ran Min--RA_Min_1
ran Max--RA_Max_1

更新

首先很抱歉,由于我遇到了一些个人问题,因此无法回复,并且由于这些问题,我无法查看堆栈溢出。请原谅我。谢谢。

没有子查询的普通查询将按预期给出结果。但我有一种情况,我必须使用子查询并且需要别名和实际字段名。

在这里提出问题,我已经截断了只有一个字段的子查询,但在实际场景中,LEFT JOIN 之后的子查询非常大并且包含许多列,例如RA_Min_1, RA_Max_1,RA_Min_2, RA_Max_2,...RA_Min_50, RA_Max_50 and some other columns.

我们正在准备动态查询,其中有时我们有RA_Min_1, RA_Max_1,有时RA_Min_2, RA_Max_2

所以,我在这里寻找带有子查询的解决方案。

任何帮助将不胜感激!!

谢谢。

标签: javamysqljdbc

解决方案


让我们将完整的查询视为多行文本。

SELECT 
  RA_Min_1 AS 'ran Min',
  RA_Max_1 AS 'ran Max' 
FROM
  `Masters` m 
  LEFT JOIN 
    (SELECT 
      mr.`Master_ID`,
      `RA_Min_1`,
      `RA_Max_1` 
    FROM
      `Master_Attribute_Range` mr 
      INNER JOIN `Masters` m 
        ON m.`Master_Type_ID` = 3 
        AND mr.`Master_ID` = m.`Master_ID`)  mar
    ON mar.Master_ID = m.`Master_ID` 
    AND m.`Master_Type_ID` = 3 
ORDER BY RA_min_1 
LIMIT 0, 25

选定的字段列表不明确。子查询别名为marhasRA_Min_1RA_Max_1fields ,因此当它与masterstable 连接时,可用字段将为m.RA_Min_1, m.RA_Max_1, mar.RA_Min_1, mar.RA_Max_1

如果显式或隐式选择子查询中的字段。例如

SELECT 
  mar.RA_Min_1 AS 'ran Min',
  mar.RA_Max_1 AS 'ran Max' 
-- ...
ORDER BY mar.RA_min_1
LIMIT 0, 25

输出

ran Min--ran Min
ran Max--ran Max

然后,结果集会丢失有关结果集元数据中列名的信息。

为了保留原始列名,尽可能选择表中的字段。

SELECT 
  m.RA_Min_1 AS 'ran Min',
  m.RA_Max_1 AS 'ran Max' 
-- ...
ORDER BY m.RA_min_1
LIMIT 0, 25;

输出

ran Min--RA_Min_1
ran Max--RA_Max_1

可以重构查询,因为子选择查询正在连接选择查询中的同一个表。

SELECT m.RA_Min_1 AS 'ran Min', m.RA_Max_1 AS 'ran Max' FROM Masters m LEFT JOIN (SELECT mr.Master_ID, RA_Min_1, RA_Max_1 FROM Master_Attribute_Range mr INNER JOIN Masters m ON m.Master_Type_ID = 3 AND mr.Master_ID = m.Master_ID ) mar ON mar.Master_ID = m.Master_ID AND m.Master_Type_ID = 3 ORDER BY m.RA_min_1 LIMIT 0, 25

这是

SELECT 
  m.RA_Min_1 AS 'ran Min',
  m.RA_Max_1 AS 'ran Max' 
FROM
  Masters AS m
  LEFT JOIN   
  Master_Attribute_Range AS mr 
  ON m.Master_Type_ID = 3 
  AND mr.Master_ID = m.Master_ID
ORDER BY m.RA_min_1
LIMIT 0, 25

推荐阅读