首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server SELECT 語句完全指南:從基礎查詢到 JOIN、排序、分頁實戰

     編輯:關於SqlServer

SELECT 核心語法結構


SELECT [ALL | DISTINCT] [TOP (n) [WITH TIES]] 
     
FROM  
[WHERE ]
[GROUP BY ]
[HAVING ]
[ORDER BY  [ASC | DESC]]
[OFFSET  ROWS FETCH NEXT  ROWS ONLY]  -- SQL 2012+
[FOR ]  -- 進階輸出

1. 基礎查詢與別名


-- 查詢所有欄位
SELECT * FROM dbo.Products;

-- 指定欄位 + 別名 (AS 可省略但建議保留)
SELECT ProductID AS ID, ProductName AS Name, UnitPrice AS Price
FROM dbo.Products;

-- 運算式與函數
SELECT ProductName, UnitPrice * UnitsInStock AS TotalValue, GETDATE() AS QueryTime
FROM dbo.Products;

2. WHERE 條件篩選


-- 比較運算子
SELECT * FROM Orders WHERE OrderDate >= '2024-01-01' AND Freight > 100;

-- 邏輯運算子 (優先順序:NOT > AND > OR,括號改變順序)
SELECT * FROM Customers 
WHERE (Country = 'USA' OR Country = 'Canada') AND Region IS NOT NULL;

-- 範圍與集合
SELECT * FROM Products WHERE UnitPrice BETWEEN 10 AND 50;
SELECT * FROM Employees WHERE City IN ('Seattle', 'Redmond', 'Kirkland');

-- 模糊查詢 (索引失效警示)
SELECT * FROM Customers WHERE ContactName LIKE 'A%';  -- 可用索引
SELECT * FROM Customers WHERE ContactName LIKE '%Smith'; -- 全掃描

-- NULL 判斷
SELECT * FROM Suppliers WHERE Fax IS NULL;
SELECT * FROM Suppliers WHERE Fax IS NOT NULL;

3. JOIN 多表關聯查詢

JOIN 類型語法結果集適用場景
INNER JOINA JOIN B ON A.ID = B.AID雙方都符合條列主從表關聯、維度表查詢
LEFT JOINA LEFT JOIN B ON A.ID = B.AID左表全保留,右表無配對則 NULL主表帶明細、報表不遺漏主記錄
RIGHT JOINA RIGHT JOIN B ON A.ID = B.AID右表全保留較少用,可改 LEFT JOIN 交換順序
FULL JOINA FULL JOIN B ON A.ID = B.AID雙方全保留雙向對帳、合併異源資料
CROSS JOINA CROSS JOIN B笛卡兒積 (M×N 列)生成測試資料、矩陣運算

實戰範例:訂單明細含產品名稱


SELECT o.OrderID, o.OrderDate, c.CompanyName AS Customer, 
       p.ProductName, od.UnitPrice, od.Quantity, od.Discount
FROM dbo.Orders o
INNER JOIN dbo.Customers c ON o.CustomerID = c.CustomerID
INNER JOIN dbo.[Order Details] od ON o.OrderID = od.OrderID
INNER JOIN dbo.Products p ON od.ProductID = p.ProductID
WHERE o.OrderDate >= '2024-01-01'
ORDER BY o.OrderID, od.ProductID;

4. 排序 ORDER BY


-- 多欄位排序:先按國家升序,同國家按城市降序
SELECT * FROM Customers ORDER BY Country ASC, City DESC;

-- 排序運算式/別名
SELECT ProductName, UnitPrice * UnitsInStock AS StockValue
FROM Products ORDER BY StockValue DESC;

-- NULL 排序:NULLS FIRST / LAST (SQL Server 2022+ / PostgreSQL)
-- SQL Server 傳統做法:
ORDER BY CASE WHEN Discount IS NULL THEN 1 ELSE 0 END, Discount DESC;

5. 分頁查詢 (現代標準語法)


-- SQL Server 2012+ 標準語法
DECLARE @PageSize INT = 20, @PageIndex INT = 3;

SELECT ProductID, ProductName, UnitPrice
FROM dbo.Products
ORDER BY ProductID
OFFSET (@PageIndex - 1) * @PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY;

-- 參數化存儲過程
CREATE PROCEDURE dbo.GetProductsPage
    @PageIndex INT = 1, @PageSize INT = 20, @TotalCount INT OUTPUT
AS
BEGIN
    SELECT @TotalCount = COUNT(*) FROM dbo.Products;
    SELECT ProductID, ProductName, UnitPrice
    FROM dbo.Products
    ORDER BY ProductID
    OFFSET (@PageIndex - 1) * @PageSize ROWS FETCH NEXT @PageSize ROWS ONLY;
END;

6. LIMIT / TOP 對比 (跨資料庫)

資料庫語法範例
SQL ServerTOP / OFFSET-FETCHSELECT TOP 10 * FROM T / OFFSET 10 ROWS FETCH NEXT 20 ROWS ONLY
MySQL / PostgreSQL / SQLiteLIMIT / OFFSETSELECT * FROM T LIMIT 20 OFFSET 10
Oracle 12c+OFFSET-FETCHOFFSET 10 ROWS FETCH NEXT 20 ROWS ONLY
Oracle 11g-ROWNUM 子查詢SELECT * FROM (SELECT a.*, ROWNUM rn FROM (SELECT * FROM T) a WHERE ROWNUM <= 30) WHERE rn > 10

7. 常見陷阱與最佳實踐

  • SELECT * 禁用於生產代碼:網路傳輸、計畫快取、Schema 變更衝擊。明確列出欄位。
  • WHERE 條件勿對欄位用函數:WHERE YEAR(OrderDate)=2024 → 索引失效。改 WHERE OrderDate >= '2024-01-01' AND OrderDate < '2025-01-01'。
  • 參數化查詢防注入:WHERE Name = @Name,絕不拼接字串。
  • DISTINCT 濫用:掩蓋 JOIN 重複列問題,優先修正 JOIN 條件/關聯基數。
  • ORDER BY 無索引支援 = 大排序:大資料量需覆蓋索引或 Top-N 排序優化。

8. 進階:條件彙總 / 樞紐分析


-- 按年月統計訂單數與金額
SELECT 
    YEAR(OrderDate) AS Year,
    MONTH(OrderDate) AS Month,
    COUNT(*) AS OrderCount,
    SUM(TotalAmount) AS TotalSales,
    SUM(CASE WHEN Status = 'Shipped' THEN 1 ELSE 0 END) AS ShippedCount
FROM Orders
GROUP BY YEAR(OrderDate), MONTH(OrderDate)
ORDER BY Year, Month;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved