需求:從 4 張以上表中查詢所需信息並顯示在 JSP 頁面。新手嘗試 UNION 失敗——UNION 要求列數、類型一致,用於縱向合併同結構結果集。多表關聯查詢應用 JOIN(內連接/左連接/右連接)橫向拼接。
| 特性 | UNION | JOIN (LEFT/RIGHT/INNER) |
|---|---|---|
| 用途 | 合併多個「同結構」查詢結果(縱向堆疊) | 關聯多張「不同結構」表,按鍵拼接列(橫向擴展) |
| 列要求 | 所有 SELECT 列數、類型、順序完全一致 | 各表保留各自列,通過 ON 條件匹配行 |
| 典型場景 | 分表存儲同類日誌、歷史數據歸檔合併 | 訂單+用戶+商品+地址 多表詳情查詢 |
SELECT
t1.id, t1.name,
t2.order_no, t2.amount,
t3.product_name, t3.price,
t4.address, t4.phone
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.user_id
LEFT JOIN table3 t3 ON t2.product_id = t3.id
LEFT JOIN table4 t4 ON t1.id = t4.user_id
WHERE t1.status = 1
ORDER BY t1.create_time DESC;
LEFT JOIN:保留左表所有行,右表無匹配則列為 NULL(適合主表駐留查詢)。INNER JOIN:僅保留雙方都匹配的行(嚴格關聯)。t1/t2 簡化寫法,避免列名衝突用 t2.name AS order_name。<%@ page import="java.sql.*, java.util.*" %>
<%
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Map<String, Object>> list = new ArrayList<>();
try {
conn = DriverManager.getConnection(url, user, pass);
String sql = "上述 JOIN 查詢 SQL";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
ResultSetMetaData meta = rs.getMetaData();
int colCount = meta.getColumnCount();
while (rs.next()) {
Map<String, Object> row = new HashMap<>();
for (int i = 1; i <= colCount; i++) {
row.put(meta.getColumnName(i), rs.getObject(i));
}
list.add(row);
}
} finally {
// 關閉資源 rs, ps, conn
}
request.setAttribute("dataList", list);
%>
<table>
<c:forEach items="${dataList}" var="row">
<tr>
<c:forEach items="${row}" var="entry">
<td>${entry.value}</td>
</c:forEach>
</tr>
</c:forEach>
</table>
STRAIGHT_JOIN 強制順序)。ALTER TABLE t2 ADD INDEX idx_user_id (user_id);。SELECT *,顯式列出所需列,減少網絡傳輸。LIMIT offset, pageSize + 覆蓋索引優化。記住:多表橫向拼接用 JOIN,縱向合併同結構用 UNION。搞清業務關係(一對一/一對多/多對多),選對 JOIN 類型,JSP 顯示自然順暢。