- 1 1. ã¯ããã«
- 1.1 èªè ã¿ãŒã²ãã
- 1.2 ROW_NUMBER()é¢æ°ã®ã¡ãªãã
- 1.3 2. ROW_NUMBERé¢æ°ãšã¯
- 1.4 ROW_NUMBERé¢æ°ã®åºæ¬æ§æ
- 1.5 åºæ¬çãªäœ¿çšäŸ
- 1.6 PARTITION BYã®äœ¿ãæ¹
- 1.7 ROW_NUMBER()é¢æ°ã®ç¹åŸŽãšæ³šæç¹
- 1.8 3. å®è·µçãªäœ¿çšäŸ
- 1.9 3-1. ã°ã«ãŒãããšã®ã©ã³ãã³ã°ä»ã
- 1.10 3-2. äžäœN件ã®ããŒã¿æœåº
- 1.11 3-3. éè€ããŒã¿ã®æœåºãšåé€
- 1.12 ãŸãšã
- 2 4. ä»ã®ãŠã£ã³ããŠé¢æ°ãšã®æ¯èŒ
- 3 5. MySQL 8.0æªæºã®ä»£æ¿ææ³
- 4 6. 泚æç¹ãšãã¹ããã©ã¯ãã£ã¹
- 5 7. ãŸãšã
1. ã¯ããã«
MySQLã®ããŒãžã§ã³8.0ã§ã¯ãå€ãã®æ°æ©èœãè¿œå ããããã®äžã§ãç¹ã«æ³šç®ãããã®ããŠã£ã³ããŠé¢æ°ã®ãµããŒãã§ãããã®èšäºã§ã¯ããã®äžã§ãé »ç¹ã«äœ¿çšãããROW_NUMBER()é¢æ°ã«çŠç¹ãåœãŠãŸãã
ROW_NUMBER()é¢æ°ã¯ãããŒã¿åæãã¬ããŒãäœæã«ãããŠåŒ·åãªæ©èœãæäŸããç¹å®ã®æ¡ä»¶ã«åºã¥ããããŒã¿ã®äžŠã¹æ¿ããé äœä»ããç°¡åã«å®çŸã§ããŸããæ¬èšäºã§ã¯ããã®é¢æ°ã®åºæ¬çãªäœ¿ãæ¹ããå¿çšäŸããããŠéå»ã®ããŒãžã§ã³ã§ã®ä»£æ¿ææ³ãŸã§ã詳ãã解説ããŸãã
èªè ã¿ãŒã²ãã
- SQLã®åºæ¬çãªç¥èãæã€åçŽè ããäžçŽè ã®æ¹
- MySQLã䜿çšããŠããŒã¿åŠçãåæãè¡ããšã³ãžãã¢ãããŒã¿ã¢ããªã¹ã
- ææ°ããŒãžã§ã³ã®MySQLã«ç§»è¡ãæ€èšããŠããæ¹
ROW_NUMBER()é¢æ°ã®ã¡ãªãã
ãã®é¢æ°ã¯ãç¹å®ã®æ¡ä»¶ã§ããŒã¿ã«å¯ŸããŠäžæã®çªå·ãå²ãåœãŠãããšãã§ããŸããããã«ãããäŸãã°ã売äžã®é«ãé ã«ã©ã³ãã³ã°ãäœæããããéè€ããŒã¿ãæœåºãæŽçããããªã©ã®äœæ¥ãç°¡æœã«èšè¿°ã§ããããã«ãªããŸãã
ãŸããéå»ã®ããŒãžã§ã³ã§ã¯ãŠãŒã¶ãŒå€æ°ã䜿ã£ãç ©éãªã¯ãšãªãå¿ èŠã§ããããROW_NUMBER()é¢æ°ã䜿ãããšã§ã³ãŒãã®ç°¡æœããšå¯èªæ§ãåäžããŸãã
ãã®èšäºã§ã¯ãå ·äœçãªã¯ãšãªäŸã亀ããªãããåå¿è ã«ãç解ãããã解説ãè¡ããŸãã次ã®ã»ã¯ã·ã§ã³ã§ã¯ããã®é¢æ°ã®åºæ¬æ§æãšåäœã«ã€ããŠè©³ããèŠãŠãããŸãã

2. ROW_NUMBERé¢æ°ãšã¯
MySQL 8.0ã§æ°ãã«è¿œå ãããROW_NUMBER()é¢æ°ã¯ãããŒã¿ã®è¡ããšã«é£çªãå²ãæ¯ããŠã£ã³ããŠé¢æ°ã®äžçš®ã§ããç¹å®ã®é åºãã°ã«ãŒãããšã«çªå·ãä»ããæ©èœãæã¡ãããŒã¿åæãã¬ããŒãäœæã§éåžžã«åœ¹ç«ã¡ãŸããããã§ã¯ããã®åºæ¬æ§æãšå ·äœäŸã亀ããªãã詳现ã«è§£èª¬ããŸãã
ROW_NUMBERé¢æ°ã®åºæ¬æ§æ
ãŸããROW_NUMBER()é¢æ°ã®åºæ¬çãªæžåŒã¯ä»¥äžã®ãšããã§ãã
SELECT
åå,
ROW_NUMBER() OVER (PARTITION BY ã°ã«ãŒãå ORDER BY 䞊ã¹æ¿ãå) AS è¡çªå·
FROM
ããŒãã«å;
åèŠçŽ ã®æå³
- ROW_NUMBER(): åè¡ã«é£çªãä»ããé¢æ°ã§ãã
- OVER: ãŠã£ã³ããŠé¢æ°ãå®çŸ©ããããã®ããŒã¯ãŒãã§ãã
- PARTITION BY: ããŒã¿ãæå®ããåã§ã°ã«ãŒãåããŸããçç¥å¯èœã§ãæå®ããªãå Žåã¯ãã¹ãŠã®è¡ã«å¯ŸããŠé£çªãæ¯ãããŸãã
- ORDER BY: çªå·ãå²ãæ¯ãé åºãæå®ããŸããããã«ããã䞊ã¹æ¿ãåºæºãèšå®ã§ããŸãã
åºæ¬çãªäœ¿çšäŸ
äŸãã°ããsalesããšããããŒãã«ãããã以äžã®ããŒã¿ãååšãããšããŸãã
employee | department | sale |
---|---|---|
A | å¶æ¥éš | 500 |
B | å¶æ¥éš | 800 |
C | éçºéš | 600 |
D | éçºéš | 700 |
ãã®ããŒã¿ã«å¯Ÿããåéšéããšã«å£²äžé¡ã®é«ãé ã§é£çªãä»ããå Žåã以äžã®ã¯ãšãªã䜿çšããŸãã
SELECT
employee,
department,
sale,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY sale DESC) AS row_num
FROM
sales;
å®è¡çµæ
employee | department | sale | row_num |
---|---|---|---|
B | å¶æ¥éš | 800 | 1 |
A | å¶æ¥éš | 500 | 2 |
D | éçºéš | 700 | 1 |
C | éçºéš | 600 | 2 |
ãã®çµæãããåéšéããšã«å£²äžé ã®ã©ã³ãã³ã°ã衚瀺ãããŠããããšãåãããŸãã
PARTITION BYã®äœ¿ãæ¹
äžèšã®äŸã§ã¯ããdepartmentãåã§ããŒã¿ãã°ã«ãŒãåããŠããŸããããã«ãããéšéããšã«å¥ã ã®é£çªãä»ããããŠããŸãã
ããPARTITION BYãçç¥ãããšããã¹ãŠã®è¡ã«å¯ŸããŠäžæ¬ã§çªå·ãå²ãæ¯ãããŸãã
SELECT
employee,
sale,
ROW_NUMBER() OVER (ORDER BY sale DESC) AS row_num
FROM
sales;
å®è¡çµæ
employee | sale | row_num |
---|---|---|
B | 800 | 1 |
D | 700 | 2 |
C | 600 | 3 |
A | 500 | 4 |
ROW_NUMBER()é¢æ°ã®ç¹åŸŽãšæ³šæç¹
- äžæã®çªå·ä»ã: åãå€ã§ãã£ãŠãé£çªã¯äžæã«ä»ããããŸãã
- NULLå€ã®æ±ã: ORDER BYã«NULLå€ãå«ãŸããå Žåãæé ã§ã¯æåã«ãéé ã§ã¯æåŸã«é 眮ãããŸãã
- ããã©ãŒãã³ã¹ãžã®åœ±é¿: 倧èŠæš¡ããŒã¿ã»ããã§ã¯ãORDER BYã®åŠçè² è·ãé«ããªããããã€ã³ããã¯ã¹ãé©åã«èšå®ããããšãéèŠã§ãã
3. å®è·µçãªäœ¿çšäŸ
ããã§ã¯ãMySQLã®ROW_NUMBER()é¢æ°ã掻çšããå ·äœçãªã·ããªãªã玹ä»ããŸãããã®é¢æ°ã¯ãããŒã¿ã®ã©ã³ãã³ã°ä»ããéè€ããŒã¿ã®åŠçãªã©ãå®åã«åœ¹ç«ã€å€ãã®ã±ãŒã¹ã§å¿çšã§ããŸãã
3-1. ã°ã«ãŒãããšã®ã©ã³ãã³ã°ä»ã
äŸãã°ãå¶æ¥ããŒã¿ãããåéšéããšã«å£²äžã®é«ãé ã§é äœãä»ããããå ŽåãèããŸãã以äžã®ããŒã¿ãäŸã«ããŸãã
employee | department | sale |
---|---|---|
A | å¶æ¥éš | 500 |
B | å¶æ¥éš | 800 |
C | éçºéš | 600 |
D | éçºéš | 700 |
ã¯ãšãªäŸ: éšéããšã®å£²äžã©ã³ãã³ã°
SELECT
employee,
department,
sale,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY sale DESC) AS rank
FROM
sales;
çµæ:
employee | department | sale | rank |
---|---|---|---|
B | å¶æ¥éš | 800 | 1 |
A | å¶æ¥éš | 500 | 2 |
D | éçºéš | 700 | 1 |
C | éçºéš | 600 | 2 |
ãã®ããã«ãåéšéããšã«å£²äžé ã§é£çªãæ¯ãããç°¡åã«ã©ã³ãã³ã°ä»ããã§ããŸãã
3-2. äžäœN件ã®ããŒã¿æœåº
次ã«ããåéšéããšã«å£²äžããã3ã®ç€Ÿå¡ãæœåºããããã±ãŒã¹ãèŠãŠã¿ãŸãã
ã¯ãšãªäŸ: äžäœN件ãæœåºããã¯ãšãª
WITH RankedSales AS (
SELECT
employee,
department,
sale,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY sale DESC) AS rank
FROM
sales
)
SELECT
employee,
department,
sale
FROM
RankedSales
WHERE
rank <= 3;
çµæ:
employee | department | sale |
---|---|---|
B | å¶æ¥éš | 800 |
A | å¶æ¥éš | 500 |
D | éçºéš | 700 |
C | éçºéš | 600 |
ãã®äŸã§ã¯ãåéšéããšã«å£²äžããã3ã®ããŒã¿ã®ã¿ãååŸããŠããŸãããã®ããã«ãROW_NUMBER()é¢æ°ã¯ã©ã³ãã³ã°ã ãã§ãªããäžäœããŒã¿ã®ãã£ã«ã¿ãªã³ã°ã«ãé©ããŠããŸãã
3-3. éè€ããŒã¿ã®æœåºãšåé€
ããŒã¿ããŒã¹ã§ã¯ãéè€ããŒã¿ãååšããããšããããŸãããã®ãããªå ŽåãROW_NUMBER()é¢æ°ã䜿çšããŠç°¡åã«åŠçã§ããŸãã
ã¯ãšãªäŸ: éè€ããŒã¿ã®æœåº
SELECT *
FROM (
SELECT
employee,
sale,
ROW_NUMBER() OVER (PARTITION BY employee ORDER BY sale DESC) AS rank
FROM
sales
) tmp
WHERE rank > 1;
ãã®ã¯ãšãªã§ã¯ãåã瀟å¡åã§è€æ°ã®ã¬ã³ãŒããååšããå Žåã«éè€ãæ€åºããŸãã
ã¯ãšãªäŸ: éè€ããŒã¿ã®åé€
DELETE FROM sales
WHERE id IN (
SELECT id
FROM (
SELECT
id,
ROW_NUMBER() OVER (PARTITION BY employee ORDER BY sale DESC) AS rank
FROM
sales
) tmp
WHERE rank > 1
);
ãŸãšã
ROW_NUMBER()é¢æ°ã¯ã
- ã°ã«ãŒãããšã®ã©ã³ãã³ã°ä»ã
- äžäœN件ã®ããŒã¿æœåº
- éè€ããŒã¿ã®æ€åºãšåé€
ãšãã£ãå€æ§ãªã·ããªãªã§æŽ»èºããŸããããã«ãããè€éãªããŒã¿åŠçãåæãç°¡åãã€å¹ççã«è¡ããããã«ãªããŸãã

4. ä»ã®ãŠã£ã³ããŠé¢æ°ãšã®æ¯èŒ
MySQL 8.0ã§ã¯ãROW_NUMBER()ã®ã»ãã«ããã©ã³ãã³ã°ä»ããé äœèšç®ã«äœ¿çšã§ãããŠã£ã³ããŠé¢æ°ãšããŠRANK()ãDENSE_RANK()ãçšæãããŠããŸãããããã®é¢æ°ã¯äŒŒããããªåœ¹å²ãæã¡ãªãããåäœãçµæã«éãããããŸããããã§ã¯ãããããã®é¢æ°ãæ¯èŒããªãããé©åãªäœ¿çšå Žé¢ã解説ããŸãã
4-1. RANK()é¢æ°
RANK()é¢æ°ã¯ãé äœä»ããè¡ãé¢æ°ã§ãããåãå€ã«å¯ŸããŠã¯åãé äœãä»ãã次ã®é äœãã¹ãããããã®ãç¹åŸŽã§ãã
åºæ¬æ§æ
SELECT
åå,
RANK() OVER (PARTITION BY ã°ã«ãŒãå ORDER BY 䞊ã¹æ¿ãå) AS é äœ
FROM
ããŒãã«å;
䜿çšäŸ
以äžã®ããŒã¿ã䜿çšããŠã売äžé äœãæ±ããŸãã
employee | department | sale |
---|---|---|
A | å¶æ¥éš | 800 |
B | å¶æ¥éš | 800 |
C | å¶æ¥éš | 600 |
D | å¶æ¥éš | 500 |
ã¯ãšãªäŸ: RANK()ã®äœ¿çš
SELECT
employee,
sale,
RANK() OVER (ORDER BY sale DESC) AS rank
FROM
sales;
çµæ:
employee | sale | rank |
---|---|---|
A | 800 | 1 |
B | 800 | 1 |
C | 600 | 3 |
D | 500 | 4 |
ç¹åŸŽ:
- åã売äžé¡ïŒ800ïŒãæã€AãšBã¯ã1äœããšããŠæ±ãããŸãã
- ãã®æ¬¡ã®é äœã§ããã2äœãã¯ã¹ããããããCã¯ã3äœãã«ãªããŸãã
4-2. DENSE_RANK()é¢æ°
DENSE_RANK()é¢æ°ã¯ãåãå€ã«åãé äœãä»ããç¹ã§ã¯RANK()ãšåæ§ã§ããã次ã®é äœãã¹ãããããŸããã
åºæ¬æ§æ
SELECT
åå,
DENSE_RANK() OVER (PARTITION BY ã°ã«ãŒãå ORDER BY 䞊ã¹æ¿ãå) AS é äœ
FROM
ããŒãã«å;
䜿çšäŸ
å ã»ã©ãšåãããŒã¿ã䜿çšããŠãDENSE_RANK()é¢æ°ãè©ŠããŸãã
ã¯ãšãªäŸ: DENSE_RANK()ã®äœ¿çš
SELECT
employee,
sale,
DENSE_RANK() OVER (ORDER BY sale DESC) AS dense_rank
FROM
sales;
çµæ:
employee | sale | dense_rank |
---|---|---|
A | 800 | 1 |
B | 800 | 1 |
C | 600 | 2 |
D | 500 | 3 |
ç¹åŸŽ:
- åã売äžé¡ïŒ800ïŒãæã€AãšBã¯ã1äœããšããŠæ±ãããŸãã
- RANK()ãšç°ãªãã次ã®é äœã¯ã2äœãããå§ãŸããããé äœã®é£ç¶æ§ãä¿ãããŸãã
4-3. ROW_NUMBER()é¢æ°ãšã®éã
ROW_NUMBER()é¢æ°ã¯ãåãå€ãæã€å Žåã§ãäžæã®çªå·ãå²ãæ¯ãç¹ã§ä»ã®2ã€ã®é¢æ°ãšç°ãªããŸãã
䜿çšäŸ
SELECT
employee,
sale,
ROW_NUMBER() OVER (ORDER BY sale DESC) AS row_num
FROM
sales;
çµæ:
employee | sale | row_num |
---|---|---|
A | 800 | 1 |
B | 800 | 2 |
C | 600 | 3 |
D | 500 | 4 |
ç¹åŸŽ:
- å€ãåãã§ãã£ãŠããäžæã®çªå·ãå²ãæ¯ãããããé äœã®éè€ã¯ãããŸããã
- ããŒã¿ã®é åºãå³å¯ã«å¶åŸ¡ãããå Žåããè¡ããšã®äžææ§ãå¿ èŠãªå Žåã«é©ããŠããŸãã
4-4. åé¢æ°ã®çšéãŸãšã
é¢æ° | é äœä»ãã®æå | 䜿çšäŸ |
---|---|---|
ROW_NUMBER() | äžæã®çªå·ãä»ãã | ããŒã¿ã«é£çªãä»ããå Žåãäžæã®èå¥ãå¿ èŠãªå Žå |
RANK() | åé äœã«ã¯åãçªå·ãä»äžãã次ã®çªå·ãã¹ããã | åå€ãããå Žåã«ã©ã³ãã³ã°é äœããã®ãŸãŸè¡šç€ºãããå Žå |
DENSE_RANK() | åé äœã«ã¯åãçªå·ãä»äžããçªå·ã¯ã¹ãããããªã | é äœã®é£ç¶æ§ãéèŠããå Žå |
ãŸãšã
ROW_NUMBER()ãRANK()ãDENSE_RANK()ã¯ããããç°ãªãå Žé¢ã§äœ¿ãåããå¿ èŠã§ãã
- ROW_NUMBER()ã¯äžæã®çªå·ãå¿ èŠãªå Žåã«é©ããŠããŸãã
- RANK()ã¯åãå€ãæã€ããŒã¿ã«åé äœãä»ãã€ã€ãé äœã®ã®ã£ããã匷調ãããå Žåã«æçšã§ãã
- DENSE_RANK()ã¯é£ç¶çãªé äœä»ããè¡ããããé äœã®ééãäžèŠãªã·ããªãªã«é©ããŠããŸãã

5. MySQL 8.0æªæºã®ä»£æ¿ææ³
MySQL 8.0ããåã®ããŒãžã§ã³ã§ã¯ãROW_NUMBER()é¢æ°ããã®ä»ã®ãŠã£ã³ããŠé¢æ°ããµããŒããããŠããŸããããããããŠãŒã¶ãŒå€æ°ã掻çšããããšã§ã䌌ããããªæ©èœãå®çŸã§ããŸããããã§ã¯ãMySQL 8.0æªæºã§ã®ä»£æ¿ææ³ãå ·äœçã«è§£èª¬ããŸãã
5-1. ãŠãŒã¶ãŒå€æ°ãå©çšããé£çªä»ã
MySQL 5.7以åã®ç°å¢ã§ã¯ããŠãŒã¶ãŒå€æ°ã䜿ã£ãŠè¡ããšã«é£çªãä»ããããšãå¯èœã§ãã以äžã®äŸãèŠãŠã¿ãŸãããã
䜿çšäŸ: éšéããšã®å£²äžã©ã³ãã³ã°
ããŒã¿äŸ:
employee | department | sale |
---|---|---|
A | å¶æ¥éš | 500 |
B | å¶æ¥éš | 800 |
C | éçºéš | 600 |
D | éçºéš | 700 |
ã¯ãšãª:
SET @row_num = 0;
SET @dept = '';
SELECT
employee,
department,
sale,
@row_num := IF(@dept = department, @row_num + 1, 1) AS rank,
@dept := department
FROM
(SELECT * FROM sales ORDER BY department, sale DESC) AS sorted_sales;
å®è¡çµæ:
employee | department | sale | rank |
---|---|---|---|
B | å¶æ¥éš | 800 | 1 |
A | å¶æ¥éš | 500 | 2 |
D | éçºéš | 700 | 1 |
C | éçºéš | 600 | 2 |
5-2. äžäœN件ã®ããŒã¿æœåº
äžäœN件ã®ããŒã¿ãååŸããã«ã¯ãåæ§ã«ãŠãŒã¶ãŒå€æ°ãå©çšããŸãã
ã¯ãšãª:
SET @row_num = 0;
SET @dept = '';
SELECT *
FROM (
SELECT
employee,
department,
sale,
@row_num := IF(@dept = department, @row_num + 1, 1) AS rank,
@dept := department
FROM
(SELECT * FROM sales ORDER BY department, sale DESC) AS sorted_sales
) AS ranked_sales
WHERE rank <= 3;
çµæ:
employee | department | sale | rank |
---|---|---|---|
B | å¶æ¥éš | 800 | 1 |
A | å¶æ¥éš | 500 | 2 |
D | éçºéš | 700 | 1 |
C | éçºéš | 600 | 2 |
ãã®ã¯ãšãªã§ã¯ãéšéããšã«ã©ã³ãã³ã°ãä»ããåŸãäžäœ3件以å ã®ããŒã¿ã®ã¿ãæœåºããŠããŸãã
5-3. éè€ããŒã¿ã®æ€åºãšåé€
éè€ããŒã¿ã®åŠçãããŠãŒã¶ãŒå€æ°ãå©çšããŠå¯Ÿå¿ã§ããŸãã
ã¯ãšãªäŸ: éè€ããŒã¿ã®æ€åº
SET @row_num = 0;
SET @id_check = '';
SELECT *
FROM (
SELECT
id,
name,
@row_num := IF(@id_check = name, @row_num + 1, 1) AS rank,
@id_check := name
FROM
(SELECT * FROM customers ORDER BY name, id) AS sorted_customers
) AS tmp
WHERE rank > 1;
ã¯ãšãªäŸ: éè€ããŒã¿ã®åé€
DELETE FROM customers
WHERE id IN (
SELECT id
FROM (
SELECT
id,
@row_num := IF(@id_check = name, @row_num + 1, 1) AS rank,
@id_check := name
FROM
(SELECT * FROM customers ORDER BY name, id) AS sorted_customers
) AS tmp
WHERE rank > 1
);
5-4. ãŠãŒã¶ãŒå€æ°ã®æ³šæç¹
- ã»ãã·ã§ã³äŸåæ§
- ãŠãŒã¶ãŒå€æ°ã¯ã»ãã·ã§ã³å ã§ã®ã¿æå¹ã§ããå¥ã®ã¯ãšãªãã»ãã·ã§ã³ã§ã¯å©çšã§ããŸããã
- åŠçé åºã®äŸå
- ãŠãŒã¶ãŒå€æ°ã¯ã¯ãšãªã®å®è¡é åºã«äŸåãããããORDER BYå¥ã®èšå®ãéèŠã§ãã
- SQLã®å¯èªæ§ãšä¿å®æ§
- ã³ãŒããè€éåãããããããMySQL 8.0以éã§ã¯ãŠã£ã³ããŠé¢æ°ã®äœ¿çšãæšå¥šããŸãã
ãŸãšã
MySQL 8.0æªæºã§ã¯ããŠã£ã³ããŠé¢æ°ã䜿çšã§ããªã代ããã«ãŠãŒã¶ãŒå€æ°ãçšããããšã§ãé£çªä»ããã©ã³ãã³ã°åŠçãå®çŸã§ããŸãããã ããã¯ãšãªãè€éã«ãªãããããããå¯èœã§ããã°æ°ããããŒãžã§ã³ãžã®ç§»è¡ãæ€èšããã®ãæãŸããã§ãããã

6. 泚æç¹ãšãã¹ããã©ã¯ãã£ã¹
MySQLã®ROW_NUMBER()é¢æ°ããŠãŒã¶ãŒå€æ°ã掻çšãã代æ¿ææ³ã¯éåžžã«äŸ¿å©ã§ãããæ£ç¢ºãã€å¹ççã«éçšããããã«ã¯æ³šæãã¹ããã€ã³ãããããŸããããã§ã¯ã䜿çšæã®æ³šæç¹ãããã©ãŒãã³ã¹æé©åã®ããã®ãã¹ããã©ã¯ãã£ã¹ã«ã€ããŠè©³ãã解説ããŸãã
6-1. ããã©ãŒãã³ã¹ã®æ³šæç¹
1. ORDER BYã®è² è·
ROW_NUMBER()é¢æ°ã¯å¿ ãORDER BYãšçµã¿åãããŠäœ¿çšããŸãããã®åŠçã§ã¯ãããŒã¿ã®äžŠã¹æ¿ããè¡ãããããã倧èŠæš¡ãªããŒã¿ã»ããã§ã¯åŠçæéãå¢å ããŸãã
察ç:
- ã€ã³ããã¯ã¹ã®æŽ»çš: ORDER BYã«äœ¿çšããåã«ã¯ã€ã³ããã¯ã¹ãèšå®ãããœãŒãåŠçãé«éåããŸãã
- LIMITã®å©çš: å¿ èŠãªããŒã¿ä»¶æ°ã ããååŸããåŠç察象ããŒã¿éãæããŸãã
äŸ:
SELECT
employee,
sale,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY sale DESC) AS rank
FROM
sales
LIMIT 1000;
2. ã¡ã¢ãªäœ¿çšéãšãã£ã¹ã¯I/Oã®å¢å€§
ãŠã£ã³ããŠé¢æ°ã¯äžæããŒãã«ãã¡ã¢ãªã䜿çšããŠåŠçããããããããŒã¿éãå¢ãããšã¡ã¢ãªæ¶è²»éããã£ã¹ã¯I/Oãå¢å ããŸãã
察ç:
- ã¯ãšãªã®åå²: åŠçãå°ããªã¯ãšãªã«åãã段éçã«ããŒã¿ãæœåºããããšã§è² è·ã軜æžããŸãã
- äžæããŒãã«ã®æŽ»çš: äžåºŠæœåºããããŒã¿ãäžæããŒãã«ã«æ ŒçŽããããããéèšåŠçãè¡ãããšã§è² æ ãåæ£ããŸãã
6-2. ã¯ãšãªãã¥ãŒãã³ã°ã®ãã€ã³ã
1. å®è¡èšç»ã®ç¢ºèª
MySQLã§ã¯EXPLAINã¹ããŒãã¡ã³ãã䜿çšããŠã¯ãšãªã®å®è¡èšç»ã確èªã§ããŸããããã«ãããã€ã³ããã¯ã¹ãæ£ãã䜿çšãããŠãããããã§ãã¯ã§ããŸãã
äŸ:
EXPLAIN
SELECT
employee,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY sale DESC) AS rank
FROM
sales;
åºåäŸ:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | sales | index | NULL | sale | 4 | NULL | 500 | Using index |
ãã®ããã«ãUsing indexãšè¡šç€ºãããŠããã°ãã€ã³ããã¯ã¹ãé©åã«å©çšãããŠããããšã瀺ããŸãã
2. ã€ã³ããã¯ã¹ã®æé©å
ORDER BYå¥ãWHEREå¥ã§äœ¿çšããåã«ã¯ãå¿ ãã€ã³ããã¯ã¹ãèšå®ããŸããããç¹ã«ä»¥äžã®ãã€ã³ãã«æ³šæããŸãã
- åäžåã€ã³ããã¯ã¹: ã·ã³ãã«ãªãœãŒãæ¡ä»¶ã®å Žåã«é©çš
- è€åã€ã³ããã¯ã¹: è€æ°åãæ¡ä»¶ã«å«ãå Žåã«æå¹
äŸ:
CREATE INDEX idx_department_sale ON sales(department, sale DESC);
3. ãããåŠçã®æŽ»çš
äžåºŠã«å€§éã®ããŒã¿ãåŠçããã®ã§ã¯ãªãããããåŠçã䜿çšããŠå°åãã«ããŒã¿ãåŠçããããšã§ãè² è·ãåæ£ã§ããŸãã
äŸ:
SELECT * FROM sales WHERE department = 'å¶æ¥éš' LIMIT 1000 OFFSET 0;
SELECT * FROM sales WHERE department = 'å¶æ¥éš' LIMIT 1000 OFFSET 1000;
6-3. ããŒã¿æŽåæ§ã®ç¶æ
1. ããŒã¿ã®æŽæ°ãšåèšç®
ããŒã¿ã®è¿œå ãåé€ã«ãã£ãŠçªå·ä»ãããããå¯èœæ§ããããŸãããã®ãããçªå·ãä»ããããŒã¿ãå¿ èŠã«å¿ããŠåèšç®ããä»çµã¿ãèšããŸãããã
äŸ:
CREATE VIEW ranked_sales AS
SELECT
employee,
sale,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY sale DESC) AS rank
FROM
sales;
ãã¥ãŒãå©çšããããšã§ãææ°ã®ããŒã¿ã«åºã¥ããã©ã³ãã³ã°ãåžžã«ç¶æã§ããŸãã
6-4. ã¯ãšãªäŸã®ãã¹ããã©ã¯ãã£ã¹
以äžã¯ãããã©ãŒãã³ã¹ãšä¿å®æ§ãèæ ®ãããã¹ããã©ã¯ãã£ã¹ã®äŸã§ãã
äŸ: äžäœN件ã®ããŒã¿æœåº
WITH RankedSales AS (
SELECT
employee,
department,
sale,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY sale DESC) AS rank
FROM
sales
)
SELECT *
FROM RankedSales
WHERE rank <= 3;
ãã®æ§é ã§ã¯ãå ±éããŒãã«åŒïŒCTEïŒã䜿çšããŠã³ãŒãã®å¯èªæ§ãšåå©çšæ§ãåäžãããŠããŸãã
ãŸãšã
ROW_NUMBER()é¢æ°ããã®ä»£æ¿ææ³ãå©çšããéã«ã¯ã次ã®ãã€ã³ããæèããããšãéèŠã§ãã
- ã€ã³ããã¯ã¹ã®æé©åã§åŠçé床ãåäžãããã
- å®è¡èšç»ã®ç¢ºèªã§ããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ããã
- ããŒã¿æŽæ°ãžã®å¯Ÿå¿ãèæ ®ããåžžã«æŽåæ§ãç¶æããä»çµã¿ãå°å ¥ããã
- ãããåŠçãCTEã掻çšããŠè² è·ãåæ£ããã
ãããã®ãã¹ããã©ã¯ãã£ã¹ã掻çšããããšã§ã倧èŠæš¡ãªããŒã¿åæãã¬ããŒãäœæãå¹ççã«è¡ããã§ãããã

7. ãŸãšã
ãããŸã§ã®èšäºã§ã¯ãMySQLã®ROW_NUMBER()é¢æ°ãäžå¿ã«ããã®åºæ¬çãªäœ¿ãæ¹ããå¿çšäŸãæ§ããŒãžã§ã³ã§ã®ä»£æ¿ææ³ã泚æç¹ãšãã¹ããã©ã¯ãã£ã¹ãŸã§ã詳ãã解説ããŠããŸããããã®ã»ã¯ã·ã§ã³ã§ã¯ãèšäºå šäœã®èŠç¹ãæ¯ãè¿ããå®è·µçãªæŽ»çšãã€ã³ãããŸãšããŸãã
7-1. ROW_NUMBER()é¢æ°ã®å©äŸ¿æ§
ROW_NUMBER()é¢æ°ã¯ãããŒã¿åæãã¬ããŒãäœæã«ãããŠä»¥äžã®ç¹ã§éåžžã«äŸ¿å©ã§ãã
- ã°ã«ãŒãããšã®é£çªä»ã: éšéããšã®å£²äžã©ã³ãã³ã°ãã«ããŽãªå¥ã®é äœä»ããç°¡åã«å®çŸã§ããŸãã
- äžäœN件ã®ããŒã¿æœåº: ç¹å®æ¡ä»¶ã«åºã¥ãããŒã¿æœåºããã£ã«ã¿ãªã³ã°ãå¹ççã«è¡ããŸãã
- éè€ããŒã¿ã®æ€åºãšåé€: ããŒã¿ã®æŽçãã¯ãªãŒãã³ã°äœæ¥ã«åœ¹ç«ã¡ãŸãã
ãããã®æ©èœã¯ãè€éãªã¯ãšãªãã·ã³ãã«ã«èšè¿°ã§ãããããSQLã®å¯èªæ§ãšä¿å®æ§ãå€§å¹ ã«åäžãããŸãã
7-2. ä»ã®ãŠã£ã³ããŠé¢æ°ãšã®æ¯èŒ
RANK()ãDENSE_RANK()ãšãã£ããŠã£ã³ããŠé¢æ°ãšæ¯èŒãããšãROW_NUMBER()ã¯åãå€ã«å¯ŸããŠäžæã®çªå·ãä»ããç¹ã§ç°ãªããŸãã
é¢æ° | ç¹åŸŽ | çšé |
---|---|---|
ROW_NUMBER() | åè¡ã«äžæã®é£çªãä»ãã | ããŒã¿ã®èå¥ãé äœä»ãã§éè€ã蚱容ããªãå Žåã«æé© |
RANK() | åé äœã«åãçªå·ãä»ãã次ã®é äœãã¹ããã | éè€ãèæ ®ããã©ã³ãã³ã°ãé äœã®ã®ã£ãããéèŠãªå Žå |
DENSE_RANK() | åé äœã«åãçªå·ãä»ããé äœã¯ã¹ãããããªã | é äœã®é£ç¶æ§ãä¿ã¡ãªããéè€ãèæ ®ããã©ã³ãã³ã°ä»ã |
é©åãªé¢æ°ã®éžæ:
çšéã«å¿ããŠæé©ãªé¢æ°ãéžæããããšã§ãå¹ççãªããŒã¿åŠçãå¯èœã«ãªããŸãã
7-3. æ§ããŒãžã§ã³ãžã®å¯Ÿå¿ç
MySQL 8.0æªæºã®ç°å¢ã§ã¯ããŠãŒã¶ãŒå€æ°ã掻çšããããšã§äŒŒãæ©èœãå®çŸã§ããããšã玹ä»ããŸããããã ãããããã®ææ³ã¯ä»¥äžã®æ³šæç¹ãèæ ®ããå¿ èŠããããŸãã
- ã³ãŒãã®è€éåã«ããå¯èªæ§ã®äœäž
- ã¯ãšãªåŠçã®æé©åãé£ããå Žåããã
- ããŒã¿ã®æŽåæ§ãä¿ã€ããã®è¿œå åŠçãå¿ èŠ
å¯èœã§ããã°ãMySQL 8.0以éã«ç§»è¡ãããŠã£ã³ããŠé¢æ°ã䜿çšããããšã匷ãæšå¥šããŸãã
7-4. ããã©ãŒãã³ã¹æé©åã®ãã€ã³ã
- ã€ã³ããã¯ã¹ã®æŽ»çš: ORDER BYã«äœ¿çšããåã«ã€ã³ããã¯ã¹ãèšå®ããŠåŠçé床ãåäžãããã
- å®è¡èšç»ã®ç¢ºèª: EXPLAINã¹ããŒãã¡ã³ãã§ããã©ãŒãã³ã¹ãäºåæ€èšŒããã
- ãããåŠçã®æ¡çš: 倧èŠæš¡ããŒã¿ã»ããã§ã¯å°åãã«åŠçããè² è·ãåæ£ããã
- ãã¥ãŒãCTEã®æŽ»çš: ã³ãŒãã®åå©çšæ§ãé«ããè€éãªã¯ãšãªãã·ã³ãã«ã«æŽçããã
ãããã®æé©åææ³ãé©çšããããšã§ãå¹ççãã€å®å®ããããŒã¿åŠçãå¯èœã«ãªããŸãã
7-5. æåŸã«
ROW_NUMBER()é¢æ°ã¯ãããŒã¿åæã®å¹çã倧å¹
ã«åäžããã匷åãªããŒã«ã§ãã
ãã®èšäºã§ã¯ãåºæ¬æ§æããå¿çšäŸã泚æç¹ã代æ¿ææ³ãŸã§è©³ãã解説ããŸããã
èªè ã®çæ§ã«ã¯ããã²å®éã«ã¯ãšãªãå®è¡ããªããæ¬èšäºã®å 容ãè©ŠããŠããã ããããšæããŸããSQLã¹ãã«ãåäžãããããšã§ãããè€éãªããŒã¿åæãã¬ããŒãäœæã«ãèªä¿¡ãæã£ãŠåãçµããããã«ãªãã¯ãã§ãã
ä»é²: åèãªãœãŒã¹
- å ¬åŒããã¥ã¡ã³ã: MySQLãŠã£ã³ããŠé¢æ°
- SQLå®è¡ç°å¢: SQL FiddleïŒãªã³ã©ã€ã³ã§SQLãå®è¡ã»ãã¹ãã§ããããŒã«ïŒ