| 特性 | 叢集索引 | 非叢集索引 |
|---|---|---|
| 每表數量 | 1 個 | 最多 999 個 (SQL 2008+) |
| 資料排序 | 葉層 = 實際資料列,邏輯序 = 物理序 | 葉層 = 索引鍵 + 書籤 (RID/叢集鍵) |
| 範圍查詢 | 極佳 | 需書籤查找 (Key Lookup) |
| 插入/更新開銷 | 較低 | 較高 (需同步維護所有非叢集索引) |
-- 非叢集
CREATE INDEX idx_orders_cust_date ON Orders (CustomerID, OrderDate);
-- 叢集 (若表無叢集)
CREATE CLUSTERED INDEX PK_Orders ON Orders (OrderID);
-- 唯一非叢集
CREATE UNIQUE NONCLUSTERED INDEX UQ_Users_Email ON Users (Email);
-- 含非鍵欄位 (覆蓋索引)
CREATE INDEX idx_Orders_Cover ON Orders (CustomerID) INCLUDE (OrderDate, TotalAmount);
SSMS「索引/鍵」對話框、維護計畫重建/重組 (`ALTER INDEX ... REBUILD/REORGANIZE`)、`sys.dm_db_index_physical_stats` 監控碎片。
-- 單列
INSERT INTO Users (Name, Email) VALUES ('John', 'john@example.com');
-- 多列
INSERT INTO Users (Name, Email) VALUES
('Alice', 'alice@example.com'), ('Bob', 'bob@example.com');
-- INSERT ... SELECT (大量轉存)
INSERT INTO Archive_Orders SELECT * FROM Orders WHERE OrderDate < '2023-01-01';
-- SELECT INTO (建新表複製)
SELECT * INTO Orders_Backup FROM Orders;
身分識別欄位:`SCOPE_IDENTITY()` 取得本會話/範圍內最新產生值 (優於 `@@IDENTITY`)。
DELETE FROM Users WHERE LastLogin < DATEADD(year, -1, GETDATE());
-- 清空表 (最小記錄、重設身分識別、不觸發 Trigger)
TRUNCATE TABLE Staging_Data;
UPDATE Products SET Price = Price * 1.1 WHERE CategoryID = 5;
-- 多欄位
UPDATE Users SET LastLogin = GETDATE(), LoginCount = LoginCount + 1 WHERE UserID = 100;
| 函數 | 說明 | 範例 |
|---|---|---|
| COUNT(*) | 列數 (含 NULL) | `SELECT COUNT(*) FROM Orders` |
| COUNT(col) | 非 NULL 個數 | `SELECT COUNT(Email) FROM Users` |
| COUNT(DISTINCT col) | 不重複非 NULL 個數 | `SELECT COUNT(DISTINCT Country) FROM Customers` |
| AVG(col) | 平均 (忽略 NULL) | `SELECT AVG(TotalAmount) FROM Orders` |
| SUM(col) | 總和 | `SELECT SUM(Qty) FROM OrderDetails` |
| MAX/MIN(col) | 最大/最小值 | `SELECT MAX(OrderDate) FROM Orders` |
別名:`SELECT AVG(Score) AS AvgScore FROM Exams` 供前端繫結。
WHERE Name LIKE 'A%' -- A 開頭
WHERE Name LIKE '%Smith' -- Smith 結尾
WHERE Name LIKE '%John%' -- 含 John
WHERE Code LIKE '[A-C]%' -- A/B/C 開頭
WHERE Code LIKE '[^0-9]%' -- 非數字開頭
WHERE Name LIKE '_a%' -- 第二字為 a
WHERE DIFFERENCE(LastName, 'Smith') >= 3 -- 發音相似
SELECT LastName, SOUNDEX(LastName) FROM Employees
LTRIM(RTRIM(Col)) -- 兩端
TRIM(Col) -- SQL 2017+ 兩端
| 代碼 | 格式範例 | 說明 |
|---|---|---|
| 112 | 20240115 | ISO yyyymmdd (可排序) |
| 120 | 2024-01-15 14:30:00 | ODBC 標準 (含毫秒用 121) |
| 111 | 2024/01/15 | 日本 yyyy/mm/dd |
| 103 | 15/01/2024 | 英式 dd/mm/yyyy |
SELECT CONVERT(VARCHAR(10), GETDATE(), 112) AS TodayISO
DATEPART(year, OrderDate) -- 年
DATEPART(month, OrderDate) -- 月
DATEPART(day, OrderDate) -- 日
DATEPART(weekday, OrderDate) -- 週幾
DATENAME(month, OrderDate) -- 月份名稱
-- 設定檔案/帳號 (一次)
EXEC msdb.dbo.sysmail_add_account_sp @account_name='AppMail', @email_address='app@corp.com', @mailserver_name='smtp.corp.com';
EXEC msdb.dbo.sysmail_add_profile_sp @profile_name='AppProfile';
EXEC msdb.dbo.sysmail_add_profileaccount_sp @profile_name='AppProfile', @account_name='AppMail', @sequence_number=1;
-- 發送
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'AppProfile',
@recipients = 'user@corp.com',
@subject = '每日報表',
@body = '請查收附件',
@query = 'SELECT TOP 10 * FROM DailySales ORDER BY SaleDate DESC',
@attach_query_result_as_file = 1,
@query_attachment_filename = 'DailySales.csv',
@query_result_separator = ',',
@query_result_header = 1;