SQL Tips - Heeyoung-Ahn/MariaDB-with-Excel-VBA GitHub Wiki

INSERT ON DUPLICATE KEY UPDATE

  • INSERT ... ON DUPLICATE KEY UPDATE is a MariaDB/MySQL extension to the INSERT statement that, if it finds a duplicate unique or primary key, will instead perform an UPDATE.
INSERT INTO ins_duplicate VALUES (4,'Gorilla') ON DUPLICATE KEY UPDATE animal='Gorilla';

CTE Recursive

-- ํŠน์ •์ผ(2019-01-31)๋ถ€ํ„ฐ ์ „์›”๋ง๊นŒ์ง€ ์กฐํšŒ์›”์„ ๋ชฉ๋ก์œผ๋กœ ๊ตฌ์„ฑ
WITH RECURSIVE query_month AS (
	SELECT '2019-01-31' AS q_month
	UNION ALL
	SELECT LAST_DAY(q_month + INTERVAL 1 MONTH)
		FROM query_month
		WHERE q_month < LAST_DAY(CURRENT_DATE - INTERVAL 1 MONTH)
)
SELECT q_month FROM query_month;

DB๊ฐ€ ๋А๋ ค์งˆ๋ฉด

  • DB์„œ๋ฒ„์—์„œ ์‹คํ–‰์ค‘์ธ ํ”„๋กœ์„ธ์Šค ํ™•์ธ: SHOW FULL processlist
  • Command Prompt์—์„œ netstat -an | findstr Host์— ์ฐํžŒ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์—ฐ๊ฒฐ์˜ ๋ฌธ์ž์—ด
    • ์˜ˆ netstat -an | findstr 51955
  • ํ•ด๋‹น Session Terminate: KILL id_no;
  • ๊ทธ๋ž˜๋„ ์•ˆ๋˜๋ฉด ์„œ๋ฒ„ ์žฌ์‹œ์ž‘
    • ์‹œ์ž‘ > services.msc ์ž…๋ ฅ ํ›„ ์—”ํ„ฐ
    • ์„ค์น˜ ์‹œ ์„ค์ •ํ•œ ์œˆ๋„์šฐ ์„œ๋น„์Šค๋ช… (๊ธฐ๋ณธ MySQL) ์„ ์ฐพ์•„ '๋‹ค์‹œ์‹œ์ž‘'

Next Record, Previous Record

SELECT * 
    FROM co_account.corporations 
    WHERE corporation_id = (SELECT MIN(corporation_id) 
                            FROM co_account.corporations 
                            WHERE corporation_id > 4 AND suspended = 0)
SELECT * 
    FROM co_account.corporations 
    WHERE corporation_id = (SELECT MAX(corporation_id)
                            FROM co_account.corporations 
                            WHERE corporation_id < 4 AND suspended = 0)

EVENT SCHEDULER

  • SET GLOBAL event_scheduler = ON;
  • SHOW VARIABLES LIKE 'event%'; -- ์ด๋ฒคํŠธ ๋ณ€์ˆ˜ ํ™•์ธ
  • SELECT * FROM information_schema.EVENTS; -- ์ด๋ฒคํŠธ ๋ชฉ๋ก ํ™•์ธ
  • my.ini์˜ [mysqld]์—๋„ event_scheduler = ON ์ถ”๊ฐ€ํ•ด์•ผ ํ•จ
    • ์˜ต์…˜์„ ์ฟผ๋ฆฌ๋กœ ๋ณ€๊ฒฝํ•ด๋„ ์„œ๋ฒ„๊ฐ€ ์žฌ์‹œ์ž‘๋˜๋ฉด ๊ธฐ๋ณธ ์„ค์ •์ธ off๋กœ ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ
CREATE EVENT IF NOT EXISTS set_today_to_refer_date
	ON SCHEDULE
	    EVERY 1 DAY STARTS '2019-11-28 00:00:01'
	ON COMPLETION PRESERVE
	ENABLE
	COMMENT '์ „ํ‘œ์กฐํšŒ๊ธฐ์ค€์ผ์˜ ๋งˆ์ง€๋ง‰๋‚ ์„ ์˜ค๋Š˜๋กœ ์—…๋ฐ์ดํŠธ'
	DO BEGIN
        -- ๋ฒ•์ธ์˜ ์›”๋ณ„ ์ด๊ณ„์ • ์›์žฅ ๋ฐ์ดํ„ฐ ๊ตฌ์„ฑ
        -- ๋ฒ•์ธ์˜ ์—ฐ๋ณ„ ์ด๊ณ„์ • ์›์žฅ ๋ฐ์ดํ„ฐ ๊ตฌ์„ฑ
        -- ์ด๊ณ„์ •์›์žฅ์˜ ๊ธฐ๊ฐ„์€ 2019๋…„ 1์›” ๋ถ€ํ„ฐ ํ˜„์žฌ๊นŒ์ง€
        CALL account_report.s_dw_general_ledger_corporation_monthly(3);
        CALL account_report.s_dw_general_ledger_corporation_yearly;
END
CREATE OR REPLACE EVENT make_refer_month
	ON SCHEDULE
		EVERY 1 MONTH
		STARTS '2020-01-01 00:10:00'
	ON COMPLETION PRESERVE
	ENABLE
	COMMENT '์กฐํšŒ์›” ์ž๋ฃŒ ์ƒ์„ฑ'
	DO
		CALL account_report.s_update_refer_month;

Date_Format

SELECT DATE_FORMAT(CURDATE(), '%Y'); -- ๋ฌธ์žํ˜•์œผ๋กœ ๋ณ€๊ฒฝ๋จ: 2020
SELECT DATE_FORMAT(CURDATE(), '%Y') - 1; -- ์ˆซ์ž๋กœ ํ‘œ์‹œ๋จ: 2,019
SELECT CAST(DATE_FORMAT(CURDATE(), '%Y') AS INT); -- ์ˆซ์ž๋กœ ๋ณ€๊ฒฝ๋จ: 2,020

STR_TO_DATE

SELECT STR_TO_DATE('20200111', '%Y%m%d'); -- 2020-01-11
SELECT STR_TO_DATE('20200111', '%Y%m%d %T'); -- 2020-01-11 00:00:00

ROW(), DENSE_ROW(), ROW_NUMBER()

  • ROW() ๋ฌธ๋ฒ•
RANK() OVER (
  [ PARTITION BY partition_expression ]
  [ ORDER BY order_list ]
) 
  • DENSE_ROW() ๋ฌธ๋ฒ•
DENSE_RANK() OVER (
  [ PARTITION BY partition_expression ]
  [ ORDER BY order_list ]
) 
  • ROW_NUMBER() ๋ฌธ๋ฒ•
ROW_NUMBER() OVER (
  [ PARTITION BY partition_expression ]
  [ ORDER BY order_list ]
) 
  • ์˜ˆ
CREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));
INSERT INTO student VALUES 
  ('Maths', 60, 'Thulile'),
  ('Maths', 60, 'Pritha'),
  ('Maths', 70, 'Voitto'),
  ('Maths', 55, 'Chun'),
  ('Biology', 60, 'Bilal'),
  ('Biology', 70, 'Roger');
SELECT 
  RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank, 
  DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank, 
  ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num, 
  course, mark, name 
FROM student ORDER BY course, mark DESC;

LAG, LEAD

  • LAG ๋ฌธ๋ฒ•
LAG (expr[, offset]) OVER ( 
  [ PARTITION BY partition_expression ] 
  < ORDER BY order_list >
)
  • LEAD ๋ฌธ๋ฒ•
LEAD (expr[, offset]) OVER ( 
  [ PARTITION BY partition_expression ] 
  [ ORDER BY order_list ]
)

Moving Average

  • ROWS BETWEEN N PRECEDING(FOLLOWING) AND N PRECEDING(FOLLOWING)
WITH t AS (
    SELECT '201201' yyyymm, 100 amt FROM dual
    UNION ALL SELECT '201202', 200 FROM dual
    UNION ALL SELECT '201203', 300 FROM dual
    UNION ALL SELECT '201204', 400 FROM dual
    UNION ALL SELECT '201205', 500 FROM dual
    UNION ALL SELECT '201206', 600 FROM dual
    UNION ALL SELECT '201207', 700 FROM dual
    UNION ALL SELECT '201208', 800 FROM dual
    UNION ALL SELECT '201209', 900 FROM dual
    UNION ALL SELECT '201210', 100 FROM dual
    UNION ALL SELECT '201211', 200 FROM dual
    UNION ALL SELECT '201212', 300 FROM DUAL
    ORDER BY yyyymm
    )
SELECT 	yyyymm,
	amt,
        (SUM(amt) OVER(ORDER BY yyyymm ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING)) AS amt_pre3,
        (SUM(amt) OVER(ORDER BY yyyymm ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING)) AS amt_fol3
  FROM t
;
WITH cte_test AS (
    SELECT 'Chun' name, 'SQL' test, 75 score FROM DUAL
    UNION ALL SELECT 'Chun', 'Tuning', 73 FROM DUAL
    UNION ALL SELECT 'Esben', 'SQL', 43 FROM DUAL
    UNION ALL SELECT 'Esben', 'Tuning', 31 FROM DUAL
    UNION ALL SELECT 'Kaolin', 'SQL', 56 FROM DUAL
    UNION ALL SELECT 'Kaolin', 'Tuning', 88 FROM DUAL
    UNION ALL SELECT 'Tatiana', 'SQL', 87
    ORDER BY name
    )
SELECT  NAME, 
        test, 
        score, 
        SUM(a.score) OVER (ORDER BY a.score RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_score 
  FROM cte_test a;
  • RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  • RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  • ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
  • ROWS BETWEEN 2 PRECEDING AND CURRENT ROW -- ์ตœ๊ทผ 3๊ฐœ์›”

DATETIME ํ˜•์‹ ์ž๋ฃŒ ์กฐํšŒ

  • ๋กœ๊ทธ ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰ ๋“ฑ
SET @start_dt = '2020-01-17'; -- ์กฐํšŒ ์‹œ์ž‘์ผ
SET @end_dt = '2020-01-17'; -- ์กฐํšŒ ์ข…๋ฃŒ์ผ

SELECT * FROM v_logs a 
    WHERE a.time_stamp >= CONVERT(@start_dt, DATETIME) AND
          a.time_stamp < CONVERT(DATE_ADD(@end_dt, INTERVAL 1 DAY), DATETIME);
          
SELECT CONVERT(@start_dt, DATETIME); -- ์กฐํšŒ ์‹œ์ž‘์ผ
SELECT CONVERT(DATE_ADD(@end_dt, INTERVAL 1 DAY), DATETIME); -- ์กฐํšŒ ์ข…๋ฃŒ์ผ

TIMESTAMP ๊ฒ€์ƒ‰

SELECT * FROM financial_db.slips a
	WHERE a.time_stamp >= CONVERT('2019-11-17', DATETIME) AND
	      a.time_stamp < CONVERT('2019-11-18', DATETIME);