SOC 직업 분류 기준
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/Objective-Arts/lens-dist --skill sql명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | sql |
| description | SQL patterns - thinking in sets, not procedures |
Channel Joe Celko: SQL guru, author of "SQL for Smarties" and "SQL Programming Style."
"SQL is a set-based, declarative language. Think in sets, not loops."
The Cardinal Sin: Writing SQL like procedural code (cursors, row-by-row processing).
-- WRONG: Procedural thinking (cursor)
DECLARE cursor_emp CURSOR FOR SELECT * FROM employees;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE employees SET salary = salary * 1.1 WHERE CURRENT OF cursor_emp;
FETCH NEXT FROM cursor_emp;
END
-- RIGHT: Set-based thinking
UPDATE employees SET salary = salary * 1.1;
-- Better than adjacency list for read-heavy trees
CREATE TABLE categories (
id INT PRIMARY KEY,
name VARCHAR(100),
lft INT NOT NULL, -- left boundary
rgt INT NOT NULL -- right boundary
);
-- Find all descendants
SELECT child.*
FROM categories parent
JOIN categories child ON child.lft BETWEEN parent.lft AND parent.rgt
WHERE parent.id = 1;
-- Find path to root
SELECT parent.*
FROM categories child
JOIN categories parent ON child.lft BETWEEN parent.lft AND parent.rgt
WHERE child.id = 10
ORDER BY parent.lft;
-- Valid time modeling
CREATE TABLE employee_salaries (
employee_id INT,
salary DECIMAL(10,2),
valid_from DATE,
valid_to DATE,
CONSTRAINT no_overlap CHECK (valid_from < valid_to),
CONSTRAINT no_gaps -- use triggers or application logic
);
-- Current salary
SELECT salary FROM employee_salaries
WHERE employee_id = 1
AND CURRENT_DATE BETWEEN valid_from AND valid_to;
-- AVOID: EAV anti-pattern
CREATE TABLE attributes (
entity_id INT,
attribute_name VARCHAR(50),
attribute_value VARCHAR(255)
);
-- PREFER: Proper table design
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2),
weight DECIMAL(8,2)
);
-- NULL is not a value, it's a marker for missing information
-- Three-valued logic: TRUE, FALSE, UNKNOWN
-- WRONG: Comparing to NULL
WHERE column = NULL -- Always UNKNOWN
WHERE column <> NULL -- Always UNKNOWN
-- RIGHT: Testing for NULL
WHERE column IS NULL
WHERE column IS NOT NULL
-- COALESCE for defaults
SELECT COALESCE(nickname, first_name, 'Unknown') AS display_name
-- SLOW: OR can prevent index usage
SELECT * FROM orders WHERE customer_id = 1 OR product_id = 2;
-- FAST: UNION ALL (if result sets are disjoint)
SELECT * FROM orders WHERE customer_id = 1
UNION ALL
SELECT * FROM orders WHERE product_id = 2 AND customer_id <> 1;
-- Find gaps in a sequence
SELECT curr.id + 1 AS gap_start,
(SELECT MIN(id) FROM sequence WHERE id > curr.id) - 1 AS gap_end
FROM sequence curr
WHERE NOT EXISTS (SELECT 1 FROM sequence WHERE id = curr.id + 1)
AND curr.id < (SELECT MAX(id) FROM sequence);
-- Find islands (consecutive sequences)
WITH numbered AS (
SELECT id, id - ROW_NUMBER() OVER (ORDER BY id) AS grp
FROM sequence
)
SELECT MIN(id) AS island_start, MAX(id) AS island_end
FROM numbered
GROUP BY grp;
-- Window function (modern SQL)
SELECT
transaction_date,
amount,
SUM(amount) OVER (ORDER BY transaction_date) AS running_total
FROM transactions;
| Anti-Pattern | Problem | Solution |
|---|---|---|
| SELECT * | Fragile, wasteful | List columns explicitly |
| Implicit joins | Hard to read, error-prone | Use explicit JOIN syntax |
| DISTINCT as fix | Hides real problem | Fix the query/schema |
| ORDER BY ordinal | Fragile | ORDER BY column_name |
| String concatenation for SQL | SQL injection | Parameterized queries |