之前在某次interview中被老外问到如何用SQL找出列上的质数和完全数的问题;我当时已经多年没有写过这种考算法和SQL技巧(纯粹的技巧)的语句了,乍遇此问题倒是有些棘手。现在录以记之,供人参考.
SQL> create table numbers(NO int) ; 表已创建。 SQL> insert into numbers select rownum from dba_objects; 已创建71937行。 SQL> commit; 提交完成。 SELECT X.NO as Primes /*查找质数(find prime number)*/ FROM Numbers N CROSS JOIN Numbers X WHERE mod(X.NO, N.NO) != 0 AND N.NO < X.NO GROUP BY X.NO HAVING(X.NO - Count(*)) = 2; PRIMES --------- 4931 4919 4909 4903 4889 4877 4871 4861 4831 4817 4813 ................ SELECT X.no as Perfect /*查找完全数,find perfect nober*/ FROM numbers N CROSS JOIN numbers X WHERE mod(X.no, N.no) = 0 and X.no > 1 AND N.no < X.no AND N.no > 0 GROUP BY X.no HAVING SUM(N.no) = X.no; PERFECT ---------- 6 28 496 ...................... 附: select ltrim(sys_connect_by_path(rownum || '*' || lv || '=' || /* SQL_99乘法口诀表*/ rpad(rownum * lv, 2), ' ')) from (select level lv from dual connect by level < 10) where lv = 1 connect by lv + 1 = prior lv; 1*1=1 2*2=4 2*1=2 3*3=9 3*2=6 3*1=3 4*4=16 4*3=12 4*2=8 4*1=4 5*5=25 5*4=20 5*3=15 5*2=10 5*1=5 6*6=36 6*5=30 6*4=24 6*3=18 6*2=12 6*1=6 7*7=49 7*6=42 7*5=35 7*4=28 7*3=21 7*2=14 7*1=7 8*8=64 8*7=56 8*6=48 8*5=40 8*4=32 8*3=24 8*2=16 8*1=8 9*9=81 9*8=72 9*7=63 9*6=54 9*5=45 9*4=36 9*3=27 9*2=18 9*1=9 with a as (select distinct round(a.x + b.x) x, round(a.y + b.y) y from (select (sum(x) over(order by n)) x, round(sum(y) over(order by n)) y from (select n, cos(n / 30 * 3.1415926) * 2 x, sin(n / 30 * 3.1415926) y from (select rownum - 1 n from all_objects where rownum <= 30 + 30))) a, (select n, (sum(x) over(order by n)) x, round(sum(y) over(order by n)) y from (select n, cos(m / 3 * 3.1415926) * 2 * 15 x, sin(m / 3 * 3.1415926) * 15 y from (select case when rownum <= 2 then 3 when rownum = 3 then -2 else -6 end m, rownum - 1 n from all_objects where rownum <= 5))) b) select replace (sys_connect_by_path(point, '/'), '/', null) star /*SQL 绘制奥运五环*/ from (select b.y, b.x, decode(a.x, null, ' ', '*') point from a, (select * from (select rownum - 1 + (select min(x) from a) x from all_objects where rownum <= (select max(x) - min(x) + 1 from a)), (select rownum - 1 + (select min(y) from a) y from all_objects where rownum <= (select max(y) - min(y) + 1 from a))) b where a.x(+) = b.x and a.y(+) = b.y) where x = (select max(x) from a) start with x = (select min(x) from a) connect by y = prior y and x = prior x + 1; with a as /*sql 绘制五角星*/ (select distinct round(sum(x) over(order by n)) x, round(sum(y) over(order by n)) y from (select n, cos(trunc(n / 20) * (1 - 1 / 5) * 3.1415926) * 2 x, sin(trunc(n / 20) * (1 - 1 / 5) * 3.1415926) y from (select rownum - 1 n from all_objects where rownum <= 20 * 5))) select replace (sys_connect_by_path(point, '/'), '/', null) star from (select b.y, b.x, decode(a.x, null, ' ', '*') point from a, (select * from (select rownum - 1 + (select min(x) from a) x from all_objects where rownum <= (select max(x) - min(x) + 1 from a)), (select rownum - 1 + (select min(y) from a) y from all_objects where rownum <= (select max(y) - min(y) + 1 from a))) b where a.x(+) = b.x and a.y(+) = b.y) where x = (select max(x) from a) start with x = (select min(x) from a) connect by y = prior y and x = prior x + 1; SELECT LPAD(MONTH, 20 - (20 - LENGTH(MONTH)) / 2) MONTH, /*sql绘制年历*/ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" FROM (SELECT TO_CHAR(dt, 'fmMonthfm YYYY') MONTH, TO_CHAR(dt + 1, 'iw') week, MAX(DECODE(TO_CHAR(dt, 'd'), '1', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Sun", MAX(DECODE(TO_CHAR(dt, 'd'), '2', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Mon", MAX(DECODE(TO_CHAR(dt, 'd'), '3', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Tue", MAX(DECODE(TO_CHAR(dt, 'd'), '4', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Wed", MAX(DECODE(TO_CHAR(dt, 'd'), '5', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Thu", MAX(DECODE(TO_CHAR(dt, 'd'), '6', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Fri", MAX(DECODE(TO_CHAR(dt, 'd'), '7', LPAD(TO_CHAR(dt, 'fmdd'), 2))) "Sat" FROM (SELECT TRUNC(SYSDATE, 'y') - 1 + ROWNUM dt FROM all_objects WHERE ROWNUM <= ADD_MONTHS(TRUNC(SYSDATE, 'y'), 12) - TRUNC(SYSDATE, 'y')) GROUP BY TO_CHAR(dt, 'fmMonthfm YYYY'), TO_CHAR(dt + 1, 'iw')) ORDER BY TO_DATE(MONTH, 'Month YYYY'), TO_NUMBER(week); MONTH Sun Mon Tue Wed Thu Fri Sat 1 1月 2010 3 4 5 6 7 8 9 2 1月 2010 10 11 12 13 14 15 16
Comment