
ãæ¬¡äžä»£é«éRDB å"Tsurugi"ãTsurugi ã«ããããµãã¯ãšãªãŒã®å®çŸ
SQL ã§ã¯ããµãã¯ãšãªãŒ (å¯åãåãã) ãå©çšããããšã§ãè€éãªåãåãããç°¡æœã«è¡šçŸããããšãã§ããŸãã
ãµãã¯ãšãªãŒãšã¯ãSQL ã®åãåããã®äžã«ãå
¥ãåã«ãªã£ãåãåãããå«ããæ©èœã§ãã
äŸãã°ã以äžã®ããã«ãå¹³åå€ãç®åºãããµãã¯ãšãªãŒãã䜿ã£ãŠãå€åŽã®ãå¹³åå€ä»¥äžã®è¡ãæœåºããã¡ã€ã³ã¯ãšãªãŒ (äž»åãåãã)ããèšè¿°ã§ããŸã:
SELECT *
FROM member
WHERE point >= (
SELECT AVG(point)
FROM member
)ãã®äŸã¯ãã¹ã«ã©ãŒãµãã¯ãšãªãŒãã®ç¯ã§ããäžåºŠåºçŸãããã¡ãã§èª¬æããŸãã
ãªããTsurugi ã§ã¯ãããã以äžã®ããŒãžã§ã³ã§ãµãã¯ãšãªãŒã®æ©èœãå®çŸããŠããŸãã
ã»Tsurugi 1.0 ïŒããŒãã«ãµãã¯ãšãªãŒ
ã»Tsurugi 1.9 ïŒå
±éããŒãã«åŒ
ã»Tsurugi 1.10 ïŒã¹ã«ã©ãŒãµãã¯ãšãªãŒãINè¿°èªãEXISTSè¿°èª
ã»Tsurugi 1.11 ïŒçžé¢ãµãã¯ãšãªãŒ
ä»åã¯ãTsurugi ã§ã¯äžèšã®ãµãã¯ãšãªãŒãã©ã®ãããªåœ¢ã§åŠçããŠããã®ããå®è¡ã«é©ãããããŒã¿ãããŒãã®åœ¢åŒã«å€æããéçšã玹ä»ããŸãã
SQL ãšããŒã¿ãããŒåŠç
Tsurugi ã§ã¯ãSQL ãå éšçã«ãããŒãã«ããŒã¿ãåŠçããããŒã¿ãããŒããžãšå€æãããããããšã«åŠçãå®çŸããŠããŸãã
äŸãã°ã以äžã®ãã㪠SQL ã«ã€ããŠèããŸã:
SELECT m.name, o.amount * m.price AS total
FROM orders AS o
JOIN item_master AS m
ON o.item_id = m.id
WHERE o.order_date = DATE '2026-01-01'äžèšã¯ããããã以äžã®åŠçãè¡ã£ãŠããŸã:
orders ããŒãã«ãš item_master ããŒãã«ãçµå
order_date ã 2026-01-01 ã®è¡ã®ã¿ãæœåº
name ãš amount * price ã®åãæœåº
ãã®çµæãã¯ã©ã€ã¢ã³ãã«è¿ã
ãããããŒã¿ãããŒãšããŠè¡šçŸãããšãäžå³ã®ãããªåŠçã®æµãã«ãªããŸã:

ããŒã¿ãããŒã®ããããã®ããŒãã¯ãTsurugi ã§ã¯ãæŒç®åããšãã³ãŸãã
äžèšã«åºçŸããæŒç®åã¯ããããã以äžã®ãããªåŠçãè¡ããã®ã§ãã

Tsurugi ã§ã¯ãäžå³ã®ãããªããŒã¿ãããŒãããšã«ãããŒã¿ãããŒäžã®æŒç®åãæžãæããããšã§ SQL ã®æé©åãè¡ã£ãããããå®è¡ã«é©ãã圢åŒã«å€æãããããŠãæçµçã«ã¯ãšãªãŒã«å¯Ÿããå®è¡èšç»ãäœæããŸãã
ïŒNoteïŒ
SQL ã®å®è¡èšç»ã«è©³ããæ¹ã¯ãfilter ã®é 眮ã«çåãæããããããããŸããã ä»åæç€ºããããŒã¿ãããŒã¯ãã¹ãŠæé©ååã®ãã®ã§ãå®éã«ã¯
filteræŒç®åã¯scan(table: orders)æŒç®åãšåäœããŠããå¹ççãªå®è¡èšç»ãäœæããŸãã
Tsurugi ã®çŸåšã®å®è£ ã«ãããŠãããµãã¯ãšãªãŒã®å±é â ããŒã¿ãããŒã®æé©å ã®é çªã§åŠçãè¡ã£ãŠããŸãã
ãµãã¯ãšãªãŒã®çš®é¡
Tsurugi ã§ã¯ããŒãã«ãµãã¯ãšãªãŒãã¹ã«ã©ãŒãµãã¯ãšãªãŒãEXISTS è¿°èªãªã©ãæ§ã ãªçš®é¡ã®ãµãã¯ãšãªãŒãå©çšå¯èœã§ãã
ä»å玹ä»ãããµãã¯ãšãªãŒã¯ãããããå
ã«èª¬æãããããªããŒã¿ãããŒã§è¡šçŸããããšãã§ããŸãã
以éã§ã¯ãããããã®ãµãã¯ãšãªãŒã«ã€ããŠé ã«èŠãŠãããŸãã
ããŒãã«ãµãã¯ãšãªãŒ
ããŒãã«ãµãã¯ãšãªãŒã¯ãæ¬æ¥ããŒãã«ãæå®ããå Žæã«ãµãã¯ãšãªãŒãæå®ããããšã§ããµãã¯ãšãªãŒã®çµæãããŒãã«ã®ä»£ãããšããŠå©çšããä»çµã¿ã§ãã
以äžã¯ããŒãã«ãµãã¯ãšãªãŒã®äŸã§ã:
SELECT *
FROM (
SELECT category, AVG(price) AS avg_price
FROM item_master
GROUP BY category
) AS summary
WHERE avg_price >= 1000äžèšã¯ item_master ããŒãã«ã® category ããšã®å¹³åäŸ¡æ Œãç®åºãããµãã¯ãšãªãŒãä»®æ³çãªããŒãã«ãšããŠå©çšããã¡ã€ã³ã¯ãšãªãŒåŽã§ãã®å¹³åäŸ¡æ Œã 1000 以äžã®è¡ãæœåºããŠããŸãã
ãã®äŸã§ããã° HAVING å¥ã䜿ã£ãŠåãåŠçãæžãããšãã§ããŸãããè€é㪠SQL ã§ã¯ããŒãã«ãµãã¯ãšãªãŒãçšããŠåŠçãåå²ããããšã§ãå
šäœã®èŠéããæ¹åã§ããŸãã
ããŠããããããŒã¿ãããŒã§è¡šçŸãããšãäžå³ã®ããã«ãªããŸã:

å³ã®ããã«ããµãã¯ãšãªãŒå ã®ããŒã¿ãã㌠(ç Žç·éšå) ãšã¡ã€ã³ã¯ãšãªãŒã®ããŒã¿ãããŒãã1ã€ã®ããŒã¿ãããŒãšããŠé£çµããããšã§ããŒãã«ãµãã¯ãšãªãŒãå®çŸããŠããŸãã
ä»åæ°ããåºçŸããæŒç®åã¯ä»¥äžã®éãã§ã:

å ±éããŒãã«åŒ
å ±éããŒãã«åŒ (Common Table Expression, CTE) ã¯ãåé ã®ããŒãã«ãµãã¯ãšãªãŒã«ååãä»ããã¡ã€ã³ã¯ãšãªãŒããããŒãã«ãšããŠåç §ã§ããããã«ãããã®ã§ãã
以äžã¯å ±éããŒãã«åŒã®äŸã§ã:
WITH summary AS (
SELECT category, AVG(price) AS avg_price
FROM item_master
GROUP BY category
)
SELECT *
FROM summary
WHERE avg_price >= 1000äžèšã¯ãåé
ã®ããŒãã«ãµãã¯ãšãªãŒã®äŸãšåãåŠçããå
±éããŒãã«åŒãçšããŠæžãæãããã®ã§ãã
ããã«å¯ŸããããŒã¿ãããŒãåé
ãšåæ§ãªã®ã§ãããã§ã¯çç¥ããŸãã
ã¹ã«ã©ãŒãµãã¯ãšãªãŒ
ã¹ã«ã©ãŒãµãã¯ãšãªãŒã¯ã1è¡1åã®çµæãè¿ããµãã¯ãšãªãŒãå€åŽã®ã¯ãšãªãŒã§ã¹ã«ã©ãŒå€ãšããŠæ±ãä»çµã¿ã§ãã
以äžã¯ãåé ã§ãæããã¹ã«ã©ãŒãµãã¯ãšãªãŒã®äŸã§ã:
SELECT *
FROM member
WHERE point >= (
SELECT AVG(point)
FROM member
)ã¹ã«ã©ãŒãµãã¯ãšãªãŒã¯æ§ã
ãªå®çŸæ¹æ³ããããŸãããTsurugi ã§ã¯ãã¹ã«ã©ãŒãµãã¯ãšãªãŒã®çµæãçµååŠçã«ãã£ãŠã¡ã€ã³ã¯ãšãªãŒã«åã蟌ãããšããææ³ã§å®çŸããŠããŸãã
ãã®ææ³ã®å©ç¹ã¯ãæ¢åã®ããŒã¿ãããŒã®æ çµã¿ãä¿ã£ããŸãŸãã¹ã«ã©ãŒãµãã¯ãšãªãŒã®è©äŸ¡ãå
šäœã§1åã«åããããšãã§ããç¹ã§ãã
ïŒNoteïŒ
ã¹ã«ã©ãŒãµãã¯ãšãªãŒã®å¥ã®å®çŸæ¹æ³ãšããŠã以äžã®ãããªãã®ããããŸã:
ã»(A) ã¡ã€ã³ã¯ãšãªãŒå ã§ã¹ã«ã©ãŒãµãã¯ãšãªãŒãåºçŸãããã³ã«ããµãã¯ãšãªãŒãå®éã«å®è¡ããŠè©äŸ¡ãã
ã»(B) ã¹ã«ã©ãŒãµãã¯ãšãªãŒãäžåºŠã ãè©äŸ¡ãããã®å€ãäžæçãªé åã«æžã蟌ãã§ãããŠãã¡ã€ã³ã¯ãšãªãŒããã¯ãã®æžã蟌ãã å€ãåç §ãã
åè ã® (A) ã¯éåžžã«åçŽãªè§£æ±ºæ¹æ³ã§ããããµãã¯ãšãªãŒã®è©äŸ¡ãã¡ã€ã³ã¯ãšãªãŒã®è¡æ°åã ãç¹°ãè¿ããããããå¹çãæªããªããŸãã åŸè ã® (B) ã¯ããã€ãã® RDBMS ã§å®éã«ãšãããŠãããããµãã¯ãšãªãŒãç¹å¥ãªåŠçãšããŠæ±ãããšããæ¹æ³ã§ãããçŸç¶ã® Tsurugi ã§ã¯æ¡çšããŸããã§ããã ãã®æ¹æ³ã¯ããµãã¯ãšãªãŒã®è©äŸ¡çµæãããŒã¿ãããŒã®å€ã«æã¡åºãããšã«ãªããã¯ãšãªãŒåŠçæ©æ§ã«ç¹å¥ãªä»çµã¿ãå¿ èŠã«ãªãããã§ãã
Tsurugi ã®ææ³ã§å ã»ã©ã® SQL ãããŒã¿ãããŒã§è¡šçŸãããšãäžå³ã®ããã«ãªããŸã:

ããŒã¿ãããŒäžã® join æŒç®åã§ã¯ã巊衚 (å³äžã® (L)) ã« member ããŒãã«å
šäœããå³è¡š (å³äžã® (R)) ã«ã¹ã«ã©ãŒãµãã¯ãšãªãŒã®çµæã§ãã1è¡1åã®å€ããšããŸãã
ãã®çµåçµæã¯ã member ããŒãã«ã®åè¡ã«ãã¹ã«ã©ãŒãµãã¯ãšãªãŒã®çµæã§ããå¹³åå€ã®åã远å ãããã®ã§ãã
ãªããã¹ã«ã©ãŒãµãã¯ãšãªãŒç¹æã®åŠçãšããŠãjoin æŒç®åã«ã¯ type: left_outer_at_most_one ãšããçµåã¿ã€ããæå®ããŠããŸãã
ããã¯ãã¹ã«ã©ãŒãµãã¯ãšãªãŒã®çµæã1è¡ä»¥äžã§ããå Žåã«ã¯ LEFT OUTER JOIN ã®ããã«æ¯ãèãã2è¡ä»¥äžã®å Žåã«ã¯ SQL å
šäœããšã©ãŒã§çµäºãããŸãã
çµæã0è¡ã§ããå Žåã远å ãããå㯠NULL ãšãªããŸãã
IN è¿°èª
IN è¿°èªã¯ããµãã¯ãšãªãŒã®çµæã«ç¹å®ã®å€ãå«ãŸããŠãããã©ãããå€å®ããããã®ä»çµã¿ã§ãã
以äžã¯ IN è¿°èªã®äŸã§ã:
SELECT *
FROM member
WHERE id IN (
SELECT member_id
FROM orders
WHERE order_date = DATE '2026-01-01'
)äžèšã¯ã orders ããŒãã«ãã 2026-01-01 ã«æ³šæããäŒå¡ã® ID ãæœåºãããã® ID ãæã€ member ããŒãã«ã®è¡ãæœåºããåŠçã§ãã
ãããŸãã«ã¯ã2026-01-01 ã«æ³šæããäŒå¡ãæœåºããããšèªããŸãã
IN è¿°èªãããŒã¿ãããŒã§è¡šãéã«ã¯ãåçµå (semi join) ãšããç¹æ®ãªçµåãå©çšããŸãã
ããã¯ã巊衚ãšå³è¡šãæ¯èŒããéã«ã巊衚ã®åè¡ã«å¯ŸããŠæ¡ä»¶ãæºããå³è¡šã®è¡ãååšãããã©ãããå€å®ããååšããå Žåã«å·Šè¡šã®è¡ãåºåãã (å³è¡šã®åã¯å«ãŸãªã) ãšããçµåã§ãã
ãããå©çšããŠããŒã¿ãããŒã衚çŸãããšãäžå³ã®ããã«ãªããŸã:

å³äžã®ããŒã¿ãããŒã§æ³šç®ãã¹ããªã®ã¯ãjoin æŒç®åã«åçµåã衚ã type: semi ãæå®ããããã®çµåæ¡ä»¶ãšããŠå·Šå³ã®åãæ¯èŒãã on: L.id = R.member_id ãäžããããŠããç¹ã§ãã
ãªãã L. ã¯å·Šè¡š (å³äžã® (L)) ã®åãã R. ã¯å³è¡š (å³äžã® (R)) ã®åã衚ãç䌌çãªæ¥é èŸã§ãããŒã¿ãããŒã®èª¬æã®ããã«æ¿å
¥ããŠããŸãã
ããã¯ã巊衚ã®å L.id ã«å¯Ÿå¿ããå³è¡šã® R.member_id ãååšããå Žåã«ããã®å·Šè¡šã®è¡ãåºåãããšããåäœã§ãã
ããã¯ãŸãã« IN è¿°èªã®åäœã衚ããŠããŸãã
EXISTS è¿°èª
EXISTS è¿°èªã¯ããµãã¯ãšãªãŒã®çµæã1è¡ä»¥äžååšãããã©ãããå€å®ããããã®ä»çµã¿ã§ãã
ãŸãã¯ä»¥äžã®ç°¡å㪠EXISTS è¿°èªã®äŸãèŠãŠã¿ãŸããã:
SELECT *
FROM member
WHERE EXISTS (
SELECT *
FROM campaign
WHERE CURRENT_DATE BETWEEN start_date AND end_date
)äžèšã¯ãéå¬äžã®ãã£ã³ããŒã³ãååšããå Žåã«ãmember ããŒãã«ã®å
šè¡ãè¿ãåŠçã§ãã
ãµãã¯ãšãªãŒãã¡ã€ã³ã¯ãšãªãŒã®åãåç
§ããŠããªããããmember ããŒãã«ã®ã©ã®è¡ã«å¯ŸããŠãå€å®çµæã¯å€ãããŸããã
ãã® EXISTS è¿°èªãã IN è¿°èªãšäŒŒããããªåœ¢åŒã§ãåçµåãå©çšããããŒã¿ãããŒã§è¡šçŸã§ããŸãã
ãã ãããããããã®è¡ãååšãããã©ããããšããæ¡ä»¶ãå€å®ãããšããç¹ããIN è¿°èªãšç°ãªããŸãã
ãããå©çšããŠããŒã¿ãããŒã衚çŸãããšãäžå³ã®ããã«ãªããŸã:

å³äžã®ãµãã¯ãšãªãŒåŽã®ããŒã¿ãããŒã¯ãåé
ã® IN è¿°èªã®äŸãšåã圢ãããŠããŸãã
IN è¿°èªãšã®å·®ç°ã¯ãåçµåã®çµåæ¡ä»¶ãå·Šå³ã®åã®æ¯èŒã§ã¯ãªããåžžã«ç (on: TRUE) ãšãªã£ãŠããç¹ã§ãã
ããã«ãããã巊衚 (å³äžã® (L)) ã®åè¡ã«å¯ŸããŠãå³è¡š (å³äžã® (R)) ã1è¡ã§ãååšãããã©ããããå€å®ããããšãã§ããŸãã
ã€ãŸãããå³è¡šã1è¡ã§ãããã°å·Šè¡šã®å
šè¡ãåºåããå³è¡šã0è¡ã§ããã°å·Šè¡šã1è¡ãåºåããªãããšããåäœã§ãã
ãã㯠EXISTS è¿°èªã®åäœãã®ãã®ã§ãã
çžé¢ãµãã¯ãšãªãŒ
ãããŸã§ã®èª¬æã§ã¯ããã¹ãŠã®ãµãã¯ãšãªãŒã¯ãéçžé¢ãµãã¯ãšãªãŒããšåŒã°ãããã®ã§ããã
Tsurugi ã§ã¯ããµãã¯ãšãªãŒã®äžããå€åŽã®ã¯ãšãªãŒã®åãåç §ãããããªããçžé¢ãµãã¯ãšãªãŒããå©çšå¯èœã§ãã
äŸãã°ã以äžã®ãã㪠SQL ãæžããŸã:
SELECT *
FROM member AS m
WHERE EXISTS (
SELECT *
FROM campaign AS c
WHERE CURRENT_DATE BETWEEN c.start_date AND c.end_date
AND m.point >= c.min_point
)äžèšã¯åé
ã® EXISTS è¿°èªã®äŸãããšã«ããµãã¯ãšãªãŒå
ã« m.point >= c.min_point ãšããæœåºæ¡ä»¶ã远å ãããã®ã§ãã
ãµãã¯ãšãªãŒå
ã® m.point ã¯ã¡ã€ã³ã¯ãšãªãŒã® member ããŒãã«ã®åãåç
§ããŠãããããããã¯çžé¢ãµãã¯ãšãªãŒã«åé¡ã§ããŸãã
SQL å
šäœãšããŠã¯ãéå¬äžã®ãã£ã³ããŒã³ãååšãããã€äŒå¡ããã®ãã£ã³ããŒã³ã®èŠå®ãã€ã³ããæºãããŠããå Žåã«ããã®äŒå¡ã®æ
å ±ãæœåºããããšèªããŸãã
åé ãŸã§ã®éçžé¢ã®äŸãšç°ãªããçžé¢ãµãã¯ãšãªãŒã®äŸã§ã¯ã¡ã€ã³ã¯ãšãªãŒã®è¡ããšã« m.point ãç°ãªãå€ããšãããããããµãã¯ãšãªãŒã¯ãã®å€ã«ãã£ãŠçµæãå€åããŸãã
çžé¢ãµãã¯ãšãªãŒã«å¯Ÿããèãæ¹
éçžé¢ãµãã¯ãšãªãŒãšåæ§ã«ãçžé¢ãµãã¯ãšãªãŒãæ§ã ãªå®çŸæ¹æ³ããããŸãã
æãåçŽãªæ¹æ³ãšããŠã¯ãã¡ã€ã³ã¯ãšãªãŒã®åè¡ã«å¯ŸããŠãæ¯åãµãã¯ãšãªãŒãå®è¡ããããšããæ¹åŒã§ãã
ããã¯ã¡ã€ã³ã¯ãšãªãŒã®è¡æ°ãéåžžã«å°ãªãå Žåã«ã¯æå¹ã§ãããã¡ã€ã³ã¯ãšãªãŒãæ°åè¡ããããããªå Žåã«ã¯ããµãã¯ãšãªãŒããã®åæ°ã ãå®è¡ãããããšã«ãªããããŸãå¹çããããããŸããã
ããã§ãTsurugi ã§ã¯ãçžé¢ãµãã¯ãšãªãŒããéçžé¢å (de-correlation)ããšããæ¹åŒã§éçžé¢ãµãã¯ãšãªãŒãžãšå€æãããã®ããã§åŠçãè¡ã£ãŠããŸãã
çžé¢ãµãã¯ãšãªãŒã®å€æ
Tsurugi ã§ã¯ãçžé¢ãµãã¯ãšãªãŒãããã©ã¡ãŒã¿ãŒåãããéçžé¢ãµãã¯ãšãªãŒããšããŠåãæ±ããŸãã
ããã§ãããã©ã¡ãŒã¿ãŒãšã¯ããµãã¯ãšãªãŒå
ã§åç
§ãããå€åŽã®ã¯ãšãªãŒã®å (çžé¢å) ãæããŸãã
ãã®ãããªèãæ¹ã®ããšã以äžã®æé ã§çžé¢ãµãã¯ãšãªãŒãããŒã¿ãããŒã§è¡šçŸããŸã:
ã¡ã€ã³ã¯ãšãªãŒãããµãã¯ãšãªãŒã«å¯ŸããŠããã©ã¡ãŒã¿ãŒã®éåãæž¡ã
ãµãã¯ãšãªãŒå ã§ããã©ã¡ãŒã¿ãŒãçµåã«ãã£ãŠåã蟌ã
äžèšã®ãã©ã¡ãŒã¿ãŒãåã蟌ãã ç¶æ ã§ãµãã¯ãšãªãŒã®åŠçãè¡ã
ã¡ã€ã³ã¯ãšãªãŒã«ããµãã¯ãšãªãŒã®çµæããã©ã¡ãŒã¿ãŒããšã«çµåãã
æç« ã ãã§ã¯äŒããã«ããã®ã§ãå®éã«ããŒã¿ãããŒãèŠãŠã¿ãŸãããã
ããŒã¿ãããŒã«å€æãã察象㮠SQL ã¯ããçžé¢ãµãã¯ãšãªãŒãã®é ã§ç޹ä»ãã以äžã® SQL ã§ã:
SELECT *
FROM member AS m
WHERE EXISTS (
SELECT *
FROM campaign AS c
WHERE CURRENT_DATE BETWEEN c.start_date AND c.end_date
AND m.point >= c.min_point
)ããã«å¯ŸããTsurugi ã§ã¯äžå³ã®ãããªããŒã¿ãããŒãçæããŸã:

å ã«æ°èŠã®æŒç®åã«ã€ããŠç޹ä»ããŸã:

çžé¢ãµãã¯ãšãªãŒã§ãã£ãŠãããµãã¯ãšãªãŒã®çµæãã¡ã€ã³ã¯ãšãªãŒãšåçµåããç¹ã¯ãéçžé¢ã® EXISTS è¿°èªãšåæ§ã§ãã
以äžã®ç®æã§éçžé¢ã®å Žåãšç°ãªããŸã:
ã¡ã€ã³ã¯ãšãªãŒåŽã® m.point åãããµãã¯ãšãªãŒåŽã«ããã©ã¡ãŒã¿ãŒããšããŠæ³šå ¥ããŠãã
ãµãã¯ãšãªãŒåŽã§ã¯ããã®ãã©ã¡ãŒã¿ãŒã join æŒç®åã§çµåãã以éã®æŒç®åã§åç §ã§ããããã«ããŠãã (å³äž [a])
ãã®ãšããäºåã«ãã©ã¡ãŒã¿ãŒã®éè€ã distinct æŒç®åã§æé€ããããšã§ãçµåçµæãå¿ èŠæå°éã«æããŠãã (å³äž [b])
åŸæ®µã® filter æŒç®åã§ã¯ãæ³šå ¥ãã m.point ãå©çšããŠãã (å³äž [c])
ãµãã¯ãšãªãŒã®çµæãã¡ã€ã³ã¯ãšãªãŒã«çµåããéã«ãæ³šå ¥ãããã©ã¡ãŒã¿ãŒã«ããæ¯èŒãè¡ã£ãŠãã
ã¡ã€ã³ã¯ãšãªãŒ (å³äžã® (L)) ãæã€ m.point ãšããµãã¯ãšãªãŒ (å³äžã® (R)) ã«æ³šå ¥ãã m.point ãçµåæ¡ä»¶ã«å©çšããŠãã (å³äž [d])
ãã®æäœã«ãã£ãŠããçŸåšã®ãã©ã¡ãŒã¿ãŒã«å¯ŸããŠåŠçãããµãã¯ãšãªãŒã®çµæãã®ã¿ãã¡ã€ã³ã¯ãšãªãŒã«çµåããããšãã§ãã
äžå³ã®ãããªããŒã¿ãããŒãçµãããšã§ãçžé¢ãµãã¯ãšãªãŒã§ãã£ãŠããµãã¯ãšãªãŒå ã® campaign ããŒãã«ãžã®ã¢ã¯ã»ã¹ãå šäœã§1åã«éå®ããŠããŸãã
ãã®ãããªéçžé¢åã®ãã1ã€ã®å©ç¹ãšããŠããéåžžã®ããŒã¿ãããŒæé©åãé©çšå¯èœã§ããããšããç¹ãæããããŸãã
å®éã«ãTsurugi ã§ã¯æé©åã®æ®µéã«ãããŠããµãã¯ãšãªãŒã¯ãã©ãããªããŒã¿ãããŒã«å€ææžã¿ã§ãããã¡ã€ã³ã¯ãšãªãŒãšãµãã¯ãšãªãŒã1æ¬ã®ããŒã¿ãããŒäžã§ãŸãšããŠæé©åãè¡ã£ãŠããŸãã
ïŒNoteïŒ
ããŒã¿ãããŒã§ã¯ããµãã¯ãšãªãŒã®çµæãã¡ã€ã³ã¯ãšãªãŒã«çµåããéã«
L.m.point = R.m.pointãšããæ¡ä»¶ãèšèŒããŠããŸããã ããã¯å®éã«ã¯
L.m.point IS NOT DISTINCT FROM R.m.pointãšããæ¯èŒæ¹æ³ãæ¡çšããŠããŸãã ããã¯ãm.pointãNULLã®å Žåã«=ã§æ¯èŒãããšæåŸ ããåäœãããªã (UNKNOWNãšè©äŸ¡ããã)ããã§ãã
察ããŠãIS NOT DISTINCT FROMã§æ¯èŒããå ŽåãNULLã©ããã®æ¯èŒã¯ç (TRUE) ãšè©äŸ¡ãããŸãã ãŸããNULLãå«ãŸãªãæ¯èŒã«ã€ããŠã¯éåžžã®=ãšåãåäœãããŸããjoinæŒç®åã®çµåæ¡ä»¶ã¯ç (TRUE) ããããä»¥å€ (FALSE,UNKNOWN) ãã§å€æãããããå®éã«ã¯å·Šå³ã®m.pointãããããNULLã®å Žåã«ã®ã¿ããããã®åäœã¯ç°ãªããŸãã
ãã®éãã¯ããã©ã¡ãŒã¿ãŒ (çžé¢å) ã«NULLãå«ãŸããå Žåã«éåžžã«éèŠã§ãã åã«L.m.point = R.m.pointãšããŠããŸããšããã©ã¡ãŒã¿ãŒã
NULLã®å Žåã«ãµãã¯ãšãªãŒã®çµæãã¡ã€ã³ã¯ãšãªãŒã«æ£ããåã蟌ããŸãããL.m.point IS NOT DISTINCT FROM R.m.pointãšããããšã§ãå·Šå³ã®m.pointãNULLã®å Žåã«çµåæ¡ä»¶ãæç«ããæ£ããåã蟌ããããã«ãªããŸãã
çžé¢ãµãã¯ãšãªãŒã®åºç€æè¡
Tsurugi ã®éçžé¢åã®å®è£
㯠"Magic De-correlation" ãšããææ³ãåºç€ã«ããŠããŸãã
以äžã¯ãã®åèæç®ã§ã:
"Magic sets and other strange ways to implement logic programs"
Francois Bancilhon et al.
PODS '86: Proceedings of the fifth ACM SIGACT-SIGMOD symposium on Principles of database systems, p1-15
DOI: 10.1145/6012.15399
"Magic is relevant"
I. S. Mumick et al.
ACM SIGMOD Record, Volume 19, Issue 2, p247-258
DOI: 10.1145/93605.98734
ä»å玹ä»ããããªãã£ãä»ã®è€éãªã±ãŒã¹ã«ã€ããŠããTsurugi ã§ã¯åæ§ã®ææ³ã§ããŒã¿ãããŒã®å€æãè¡ããSQL ãåŠçããŠããŸãã
ææ³ã«ã€ããŠè©³ããã¯äžèšã®æç®ãåç
§ããŠãã ããã
ãµãã¯ãšãªãŒé¢é£ã®çŸåšã®å¶é
ãµãã¯ãšãªãŒã«ã¯ãçŸç¶ã§ä»¥äžã®è¡šã«æããæ©èœã®å¶éããããŸãã
ãããã®å¶éã¯å°æ¥ã®ããŒãžã§ã³ã§å¯Ÿå¿ããããšãæ€èšããŠããŸãã

ããã§ãããåé¢å¯èœãªãã£ã«ã¿ãŒæ¡ä»¶ããšã¯ã WHERE ã HAVING ãªã©ã®ãã£ã«ã¿ãŒæ¡ä»¶ãšããŠåç¬ã§å©çšãããŠãããããããã¯ããã«çŽæ¥çŸãã AND ãŸã㯠NOT ã®çŽæ¥ã®ãªãã©ã³ãã§ããããšãæããŸãã
ïŒNoteïŒ
å¶éé ç®ã«INè¿°èªé¢é£ãå€ãã®ã¯ãINè¿°èªã«ãããNULLã®æ¬è³ªçãªåãæ±ãã®é£ããã«èµ·å ããŠããŸãã ããšãã°ãx NOT IN (SELECT y FROM t)ãšããåŒãè§£éããéããµãã¯ãšãªãŒã1ã€ã§ãNULLãè¿ãå Žåã ãã以å€ãã©ã®ãããªå€ã§ãã£ãŠãNOT INã®çµæãTRUEãšãªãããšã¯ãããŸããã ä»å玹ä»ããåçµå (semi join) ãããã®åŠå®ã§ããåçµå (anti join) ã§ã¯äžèšã®ãããªåŠçãçŽæ¥è¡šçŸã§ããŸããã
éã«EXISTSè¿°èªã¯ãããµãã¯ãšãªãŒã®çµæã1è¡ä»¥äžååšãããã©ããããšããå€å®ãè¡ãããµãã¯ãšãªãŒã®è¿ãåã ã®å€ã«åœ±é¿ãåããŸããã ãã®ãããäžèšã®ãããªãNULLãè¿ããã©ããããšããåé¡èªäœããããŸããã ãã¡ãã¯ãä»å玹ä»ããåçµåã«ããå€ææ¹æ³ããå·Šå€çµå (LEFT OUTER JOIN) ãå©çšãã倿ã§çŽ çŽã«è¡šçŸã§ããŸãã
ãŸãšã
以äžã Tsurugi ã«ããããµãã¯ãšãªãŒã®å®çŸæ¹æ³ã®æŠèŠã§ãã
玹ä»ããããã«ãTsurugi ã§ã¯ãµãã¯ãšãªãŒãšã¡ã€ã³ã¯ãšãªãŒã1ã€ã®ããŒã¿ãããŒã«çµ±åããããšã§ãSQL å šäœã倧ããªããŒã¿ãããŒãšããŠåŠçããŠããŸãã
éçžé¢ã®ãµãã¯ãšãªãŒã§ã¯ããµãã¯ãšãªãŒã®çµæãã¡ã€ã³ã¯ãšãªãŒã« join æŒç®åãçšããŠåã蟌ã¿ãŸããã
çžé¢ã®ãµãã¯ãšãªãŒã§ã¯ãã¡ã€ã³ã¯ãšãªãŒã®åããã©ã¡ãŒã¿ãŒãšããŠãµãã¯ãšãªãŒå ã«æ³šå ¥ãããµãã¯ãšãªãŒå ã§ã¯ join æŒç®åãçšããŠãã©ã¡ãŒã¿ãŒãåã蟌ã¿ãŸããã
ãµãã¯ãšãªãŒã®çš®é¡ããšã®åãèŸŒã¿æ¹ã¯ãäžèšã®è¡šã®ããã«ãŸãšããããŸã:

Tsurugi ã§ã¯ããã¹ãŠã®åŠçããã©ãããªããŒã¿ãããŒäžã§è¡ã£ãŠããŸãã
ãµãã¯ãšãªãŒãšããç¹æ®ãªæ§é ã§ãã£ãŠããäžèšã®è¡šã®ããã«çµå ( join æŒç®å) çãå©çšããããšã§ãã¡ã€ã³ã¯ãšãªãŒãšãµãã¯ãšãªãŒãã€ãªããããŒã¿ãããŒäžã§èªç¶ã«åŠçã衚çŸã§ããããšãããããŸãã
ãããŠããããã®ããŒã¿ãããŒã¯ãSQL ãšããŒã¿ãããŒåŠçãã§è¿°ã¹ãéããæé©åãçµãŠå®è¡èšç»ã«å€æãããŸãã
ãã ãããã®æ¹æ³ã«ã¯åé¡ããããŸãã
ç¹ã«çžé¢ãµãã¯ãšãªãŒã§ã¯ãéçžé¢åã®éã«ã¡ã€ã³ã¯ãšãªãŒãããã©ã¡ãŒã¿ãŒ (çžé¢å) ããµãã¯ãšãªãŒã«æ³šå
¥ããŠããŸãã
ãã®ãšããæ³šå
¥ãããã©ã¡ãŒã¿ãŒã®çš®é¡æ°ãšããµãã¯ãšãªãŒãåŠçããããŒãã«ã®è¡æ°ãšã®çŽç© (æãç®) ããäžæçã«ã¡ã¢ãªãŒäžã«å±éãããŸã (å€ãã®ã±ãŒã¹ã§ã¯ãæé©åã«ãã£ãŠããããã¯ãã£ãšå°ãªãä»¶æ°ã«ã¯ãªããŸã)ã
ãã®ãããäžéšã®ã±ãŒã¹ã«ã€ããŠã¯ããã¡ã€ã³ã¯ãšãªãŒã®1è¡ãã€ã§ããµãã¯ãšãªãŒãè©äŸ¡ããããšããåçŽãªæ¹æ³ (demanding evaluation) ã®ã»ããããŸãåãå ŽåããããŸãã
ãã®ã¡ã¢ãªãŒäœ¿çšéãå®è¡åã«æšå®ããå®è¡èšç»ãåãæ¿ããæ¹åŒãªã©ãæ€èšããŠããŸãã
ãã®ä»ã®å"Tsurugi"ã䜿ãéã«åœ¹ç«ã€Tipséã¯ã³
次äžä»£é«éRDBå"Tsurugi"ã¯ããªãŒãã³ãœãŒã¹ã§å
¬éäžã§ãã
ãã²ããŠã³ããŒãããŠã¿ãŠãè§Šã£ãŠã¿ãŠãã ããã