資料結構:
`Student(S#, Sname, Sage, Ssex)`
`Course(C#, Cname, T#)`
`SC(S#, C#, score)`
`Teacher(T#, Tname)`
| 題號 | 核心考點 | 關鍵技巧 |
|---|---|---|
| 1, 8 | 同一表多次自聯結比較不同課程成績 | 別名 + 子查詢/自聯結 |
| 2, 24, 33 | 分組聚合 + HAVING 篩選 | AVG/COUNT/SUM + HAVING |
| 3, 17, 22 | 多表聯結 + 條件聚合 / 行轉列 | LEFT JOIN + CASE WHEN / PIVOT 思想 |
| 5, 7, 47 | NOT IN / NOT EXISTS 反向關聯 | 子查詢排除 |
| 6, 12 | EXISTS 相關子查詢 | 半連結語意 |
| 13 | UPDATE 含子查詢計算平均值 | 相關子查詢更新 |
| 14 | 關係除法 (Relational Division) | GROUP BY + HAVING COUNT = 總數 |
| 19, 20, 23 | 條件聚合 (CASE WHEN 在聚合函數中) | 單掃描多指標 |
| 25, 43 | 分組 Top-N | 相關子查詢 TOP / ROW_NUMBER() (2005+) |
| 48 | 多條件篩選後聚合 | 子查詢 + GROUP BY |
-- 建庫/刪庫
CREATE DATABASE db_name; DROP DATABASE db_name;
-- 建表/刪表/改表
CREATE TABLE t (id INT PRIMARY KEY, name NVARCHAR(50) NOT NULL);
ALTER TABLE t ADD col INT DEFAULT 0;
ALTER TABLE t ALTER COLUMN col BIGINT;
ALTER TABLE t DROP COLUMN col;
DROP TABLE t;
-- 索引/視圖
CREATE INDEX ix_t_col ON t(col);
CREATE VIEW v AS SELECT id, name FROM t WHERE ...;
-- 基礎增刪改查
INSERT INTO t (id, name) VALUES (1, 'a');
UPDATE t SET name='b' WHERE id=1;
DELETE FROM t WHERE id=1;
SELECT * FROM t WHERE name LIKE N'%關鍵字%';
| 需求 | T-SQL |
|---|---|
| 隨機抽樣 10 列 | SELECT TOP 10 * FROM t ORDER BY NEWID(); |
| 刪除重複列 (保留最大 ID) | DELETE t WHERE id NOT IN (SELECT MAX(id) FROM t GROUP BY col1, col2); |
| 查詢所有使用者表 | SELECT name FROM sys.objects WHERE type='U'; |
| 查詢表欄位清單 | SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('t'); |
| 檢查備份檔有效性 | RESTORE VERIFYONLY FROM DISK='path.bak'; |
| 修復資料庫 (允許資料遺失) | ALTER DATABASE db SET SINGLE_USER; DBCC CHECKDB(db, REPAIR_ALLOW_DATA_LOSS); ALTER DATABASE db SET MULTI_USER; |
| 跨伺服器查詢 (Linked Server) | SELECT * FROM [LinkedSrv].[DB].[dbo].[Table]; |
| 字串分割函數 (CSV → 資料列) | 見下方 Split 函數定義 |
CREATE FUNCTION dbo.Split(@str NVARCHAR(MAX), @sep NCHAR(1))
RETURNS @t TABLE (val NVARCHAR(4000))
AS BEGIN
DECLARE @pos INT = CHARINDEX(@sep, @str);
WHILE @pos > 0 BEGIN
INSERT @t VALUES(SUBSTRING(@str, 1, @pos-1));
SET @str = SUBSTRING(@str, @pos+1, LEN(@str));
SET @pos = CHARINDEX(@sep, @str);
END
IF @str <> '' INSERT @t VALUES(@str);
RETURN;
END;
SQL 2016+ 直接使用 `STRING_SPLIT()` (不保證順序) 或 `OPENJSON()` (保持順序)。