ã¯ããã«
ããåæé¢æ°ã®è¡æï¼åç·¨ï¼ãã«å¼ãç¶ããCodeZineã®ããã¯æ°ã®è¨äºã§è¨è¼ãããSQLããåæé¢æ°ã使ã£ã¦è¨è¿°ãã¦ããã¾ãã
対象èªè
- SQLã®å¯èªæ§ãåä¸ããããæ¹
- SQLã®ããã©ã¼ãã³ã¹ãåä¸ããããæ¹
ããã®è¨äºã§ã¯ããèªå·±çµåã®ä½¿ãæ¹ãã¨ããç¸é¢ãµãã¯ã¨ãªã§è¡ã¨è¡ãæ¯è¼ãããã«è¨è¼ããã¦ããSQLãåæé¢æ°ã使ã£ã¦è¨è¿°ãã¦ããã¾ãã®ã§ãå ã«èªã¾ããæ¹ãç解ãããããã¨æãã¾ãã
å¿ è¦ãªç°å¢
ãæ¬ç¨¿ã§æ±ãSQLã¯ãOracle 10.2.0.1.0ã§åä½ç¢ºèªãã¾ãããã½ã¼ã¹ã³ã¼ãã¯DB2 V9.1ã§ãåä½ç¢ºèªãã¾ããããã®ä»ã
- Oracle9i以é
- DB2
- SQL Server 2005
ãã§ãå¿ç¨ã§ãã¾ãã
1. é¨åçã«ä¸ä¸è´ãªãã¼ã®æ¤ç´¢
ãã¾ãã¯é¨åçã«ä¸ä¸è´ãªãã¼ãæ¤ç´¢ããSQLã«ã¤ãã¦ã§ãããèªå·±çµåã®ä½¿ãæ¹ãã§ã¯ã以ä¸ã®èªå·±éçå¤çµåã使ãSQLãæ示ããã¦ãã¾ãã
SELECT DISTINCT A1.name, A1.address FROM Addresses A1, Addresses A2 WHERE A1.family_id = A2.family_id AND A1.address <> A2.address ;
ããããåæé¢æ°ã§æ¸ãæãã¦ã¿ã¾ããã¾ãã¯ãå°ããã¼ã¿ãå¤æ´ãããAddressesããã¼ãã«ã®ãã¼ã¿ã¨åºåçµæãèãã¾ãã
name | family_id | address |
åç° ç¾©æ | 100 | 港åºèãé3-2-29 |
åç° ç±ç¾ | 100 | 港åºèãé3-2-92 |
å è¤ è¶ | 200 | æ°å®¿åºè¥¿æ°å®¿2-8-1 |
å è¤ å | 200 | æ°å®¿åºè¥¿æ°å®¿2-8-1 |
ãã¼ã 㺠| 300 | ãã¼ã«ã¼è¡221B |
ã¯ãã½ã³ | 400 | ãã¼ã«ã¼è¡221B |
ç¹ç° ä¿¡é· | 500 | äº¬é½ |
ç¹ç° ä¿¡å¿ | 500 | äº¬é½ |
ç¹ç° é·ç | 500 | äº¬é½ |
å¾³å· å®¶åº· | 600 | é¢ã¶å |
æ¾å¹³ å¿ å | 600 | é¢ã¶å |
å¾³å· ç§å¿ | 600 | ä¸ç°å |
name | address |
åç° ç¾©æ | 港åºèãé3-2-29 |
åç° ç±ç¾ | 港åºèãé3-2-92 |
å¾³å· å®¶åº· | é¢ã¶å |
æ¾å¹³ å¿ å | é¢ã¶å |
å¾³å· ç§å¿ | ä¸ç°å |
ãæç¶ãåã®è¨èªã§ããã°ã
- family_idã®æé ã«ã½ã¼ã
- family_idã®æå°å¤ããã«ã¼ãéå§
- family_idã®å¤ãå¤æ°ã«ä¿å
- addressã®å¤ãå¤æ°ã«ä¿å
- addressã®å¤ãéã£ããåºå
- family_idããã¬ã¤ã¯ãããã3ã¸
- family_idããã¬ã¤ã¯ããªãã£ããã5ã¸
ãã¨ãã£ãå¦çãè¡ãã¨æãã¾ãããåæé¢æ°ã使ã£ãSQLã§ãä¼¼ããããªèãæ¹ã使ãã¾ãã
select name,address from (select name,address, count(distinct address) over(partition by family_id) as distinctAddressCount from Addresses) where distinctAddressCount > 1;
ãpartition by
å¥ã«ãfamily_idããæå®ãã¦ããfamily_idããçããé¨åéåã§ã®count(distinct address)
ãæ±ãã¦ã¾ããpartition by
å¥ã使ã£ãSQLã®ã¤ã¡ã¼ã¸ã¯ããããªãã¾ãã
ãå¾ã¯ãcount(distinct address)
ãã1ãã大ãããã¨ããå¤å´ã®select
æã®where
å¥ã§æ¡ä»¶ã¨ãã¦ã¾ããåããfamily_idãã§ããaddressãã2éã以ä¸ãã£ãããåºå対象ã«ãªãã¨ããèãæ¹ã§ãã
ãDB2ã§ã¯ãåæé¢æ°ã®count
é¢æ°ã§distinct
ãªãã·ã§ã³ã使ããªãã®ã§ãä¸è¨ã®SQLã¨ãªãã¾ãã
--éã½ã¼ãã使ã£ã¦ã --count(distinct address) over(partition by family_id)ãæ±ããæ¹æ³ select name,address from (select name,address, -1+dense_rank() over(partition by family_id order by address asc) +dense_rank() over(partition by family_id order by address desc) as distinctAddressCount from Addresses) dummy where distinctAddressCount > 1; --æå°å¤ã¨æ大å¤ãç°ãªãã°ãä½æã2件以ä¸ããã¨èããæ¹æ³ select name,address from (select name,address, max(address) over(partition by family_id) as MaxAddress, min(address) over(partition by family_id) as MinAddress from Addresses) dummy where MaxAddress != MinAddress;