??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美精品一区二区三区蜜桃,在线亚洲伦理,国产系列电影在线播放网址http://www.aygfsteel.com/jxhkwhy/category/31489.htmlzh-cnWed, 14 May 2008 19:24:51 GMTWed, 14 May 2008 19:24:51 GMT60SQL语句-更改累计和中的?/title><link>http://www.aygfsteel.com/jxhkwhy/articles/200496.html</link><dc:creator>UR?/dc:creator><author>UR?/author><pubDate>Wed, 14 May 2008 13:51:00 GMT</pubDate><guid>http://www.aygfsteel.com/jxhkwhy/articles/200496.html</guid><wfw:comment>http://www.aygfsteel.com/jxhkwhy/comments/200496.html</wfw:comment><comments>http://www.aygfsteel.com/jxhkwhy/articles/200496.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200496.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jxhkwhy/services/trackbacks/200496.html</trackback:ping><description><![CDATA[<p>问题:Ҏ另一列中的g改篏计和中的倹{假设一个场景,要显CZ用卡账号的事务处理历史以及每ơ事务处理洲改篏计和中的倹{假设一个场景,要显CZ用卡账号的事务处理历史以及每ơ事务处理之后的当前余额。在q个例子中,用下面给出的视图VQ?/p> <p>create view V (id,amt,trx)</p> <p>as</p> <p>select 1, 100, 'PR' from t1 union all</p> <p>select 2, 100, 'PR' from t1 union all</p> <p>select 3, 50,   'PY' from t1 union all</p> <p>select 4, 100, 'PR' from t1 union all</p> <p>select 5, 200, 'PY' from t1 union all</p> <p>select 6, 50,   'PY' from t1 </p> <p>select * from V </p> <p>ID         AMT TR</p> <p>-- ---------- --</p> <p>1         100 PR</p> <p>2         100 PR</p> <p>3          50 PY</p> <p>4         100 PR</p> <p>5         200 PY</p> <p>6          50 PY</p> <p>ID列唯一标识每次事务处理。AMT列表C每ơ事务处理(取款或存ƾ)涉及的金额。TRX列定义了事务处理的类型;取款?#8220;PY”Q存ƾ是“PR”。如果TRX值是PYQ则惌从篏计和中减去AMTg表的金额Q如果TRX值是PRQ则惌l篏计和加上AMTg表的金额。最后应该返回如下结果集Q?/p> <p>TRX_TYPE         AMT     BALANCE</p> <p>-------- ---------- ----------</p> <p>PURCHASE         100         100</p> <p>PURCHASE         100         200</p> <p>PAYMENT           50         150</p> <p>PURCHASE         100         250</p> <p>PAYMENT          200          50</p> <p>PAYMENT           50           0</p> <p>解决Ҏ</p> <p>DB2和Oracle </p> <p>使用H口函数SUM OVER创徏累计和,q用CASE表达式判断事务处理的cdQ?/p> <p>1   select case when trx = 'PY'</p> <p>2               then 'PAYMENT'</p> <p>3               else 'PURCHASE'</p> <p>4           end trx_type,</p> <p>5           amt,</p> <p>6           sum(</p> <p>7            case when trx = 'PY'</p> <p>8               then -amt else amt</p> <p>9            end</p> <p>10          ) over (order by id,amt) as balance</p> <p>11     from V</p> <p>MySQL、PostgreSQL和SQL Server</p> <p>使用标量子查询创建篏计和Qƈ使用CASE表达式判断事务处理的cdQ?/p> <p>1   select case when v1.trx = 'PY'</p> <p>2               then 'PAYMENT'</p> <p>3               else 'PURCHASE'</p> <p>4           end as trx_type,</p> <p>5           v1.amt,</p> <p>6           (select sum(</p> <p>7                    case when v2.trx = 'PY'</p> <p>8                         then -v2.amt else v2.amt</p> <p>9                    end</p> <p>10                   )</p> <p>11              from V v2</p> <p>12             where v2.id <= v1.id) as balance</p> <p>13     from V v1</p> <p>讨论</p> <p>CASE表达式判断是该给累计和加上当前的AMTD是从中减d前的AMT?。如果事务处理是取款Q则把AMT更改|q样减了累计和。CASE表达式的l果如下所C:</p> <p>select case when trx = 'PY'</p> <p>             then 'PAYMENT'</p> <p>             else 'PURCHASE'</p> <p>        end trx_type,</p> <p>        case when trx = 'PY'</p> <p>             then -amt else amt</p> <p>        end as amt</p> <p>   from V </p> <p>TRX_TYPE        AMT</p> <p>-------- ---------</p> <p>PURCHASE        100</p> <p>PURCHASE        100</p> <p>PAYMENT         -50</p> <p>PURCHASE        100</p> <p>PAYMENT        -200</p> <p>PAYMENT         -50</p> <p>在确定了事务处理cd之后Q就可以从篏计和中加上或者减去AMT倹{有关窗口函数SUM OVER或标量子查询如何创徏累计和的说明Q请参阅“计算累计?#8221;?/p> <img src ="http://www.aygfsteel.com/jxhkwhy/aggbug/200496.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jxhkwhy/" target="_blank">UR?/a> 2008-05-14 21:51 <a href="http://www.aygfsteel.com/jxhkwhy/articles/200496.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL语句-把字母数字串转换为数?/title><link>http://www.aygfsteel.com/jxhkwhy/articles/200495.html</link><dc:creator>UR?/dc:creator><author>UR?/author><pubDate>Wed, 14 May 2008 13:50:00 GMT</pubDate><guid>http://www.aygfsteel.com/jxhkwhy/articles/200495.html</guid><wfw:comment>http://www.aygfsteel.com/jxhkwhy/comments/200495.html</wfw:comment><comments>http://www.aygfsteel.com/jxhkwhy/articles/200495.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200495.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jxhkwhy/services/trackbacks/200495.html</trackback:ping><description><![CDATA[<p>问题:对于字母数字的数据,只返回数字倹{从字符?#8220;paul123f321”中返?23321?/p> <p>解决Ҏ</p> <p>DB2</p> <p>使用函数TRANSLATE和REPLACEQ从字母数字串中提取数字字符Q?/p> <p>1 select cast(</p> <p>2         replace(</p> <p>3       translate( 'paul123f321',</p> <p>4                  repeat('#',26),</p> <p>5                  'abcdefghijklmnopqrstuvwxyz'),'#','') </p> <p>6         as integer ) as num</p> <p>7    from t1</p> <p>Oracle和PostgreSQL</p> <p>使用函数TRANSLATE和REPLACEQ可以从包含字母数字的字W串中提取数字字W:</p> <p>1 select cast(</p> <p>2         replace(</p> <p>3       translate( 'paul123f321',</p> <p>4                  'abcdefghijklmnopqrstuvwxyz',</p> <p>5                  rpad('#',26,'#')),'#','') </p> <p>6         as integer ) as num</p> <p>7   from t1    </p> <p>MySQL和SQL Server</p> <p>到本书编写时为止Q这两个供应商都不支持TRANSLATE函数Q因此这里不能给x案了?/p> <p>讨论</p> <p>两种解决Ҏ的唯一差别是语法,DB2使用函数REPEAT代替RPADQ而且TRANSLATE参数列表的顺序也不同。以下的解释采用了Oracle/PostgreSQL解决ҎQ?DB2也类伹{如果从里向外运行该查询Q仅仅从TRANSLATE开始)Q就会发现这非常单。首先,TRANSLATE把非数字字符转换?#8220;#”Q?/p> <p>select translate( 'paul123f321',</p> <p>                   'abcdefghijklmnopqrstuvwxyz',</p> <p>                   rpad('#',26,'#')) as num</p> <p>   from t1 </p> <p>NUM</p> <p>-----------</p> <p>####123#321</p> <p>׃现在所有非数字字符都用“#”表示了,因此只需使用REPLACEL它们Q然后把l果转换为数倹{这个特D的例子其单,因ؓ字符串中只有字母和数字。如果还有其他字W,那么用另一U方法会更容易:不是扑և非数字字WƈL它们Q而是扑և所有数字字W,q去掉不属于q些字符范围的其他字W。下面的例子会有助于理解q种技巧:</p> <p>select replace(</p> <p>      translate('paul123f321',</p> <p>        replace(translate( 'paul123f321',</p> <p>                           '0123456789',</p> <p>                           rpad('#',10,'#')),'#',''),</p> <p>                rpad('#',length('paul123f321'),'#')),'#','') as num</p> <p>   from t1 </p> <p>NUM</p> <p>------</p> <p>123321</p> <p>较之原始ҎQ该解决Ҏ看v来有点儿费解Q但如果把它分解开来就Ҏ理解了。观察一下最内层的TRANSLATE调用Q?</p> <p>select translate( 'paul123f321',</p> <p>                   '0123456789',</p> <p>                   rpad('#',10,'#'))</p> <p>   from t1 </p> <p>TRANSLATE('</p> <p>-----------</p> <p>paul###f###</p> <p>与原来方案不同的是,它没有用“#”字符替换每个非数字字W,而是?#8220;#”字符替换所有数字字W。接下来Q去掉所?#8220;#”Q这P只剩下非数字字符Q?/p> <p>select replace(translate( 'paul123f321',</p> <p>                           '0123456789',</p> <p>                           rpad('#',10,'#')),'#','')</p> <p>   from t1 </p> <p>REPLA</p> <p>-----</p> <p>paulf</p> <p>下一步,再次调用TRANSLATEQ这ơ用“#”字符替换原始字符串中的所有非数字字符Q前面查询的l果Q:</p> <p>select translate('paul123f321',</p> <p>        replace(translate( 'paul123f321',</p> <p>                           '0123456789',</p> <p>                           rpad('#',10,'#')),'#',''),</p> <p>                rpad('#',length('paul123f321'),'#'))</p> <p>   from t1 </p> <p>TRANSLATE('</p> <p>-----------</p> <p>####123#321</p> <p>到这里停一停,验一下最外层的TRANSLATE调用。RPAD的第二个参数QDB2中REPEAT的第二个参数Q是原始字符串的长度。这样做很方便,因ؓ是没有Q何字W出现的ơ数会比它所在的整个字符串长。现在,?#8220;#”字符替换所有非数字字符Q最后一步,使用REPLACEL所?#8220;#”。至此,仅剩下数字?/p> <img src ="http://www.aygfsteel.com/jxhkwhy/aggbug/200495.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jxhkwhy/" target="_blank">UR?/a> 2008-05-14 21:50 <a href="http://www.aygfsteel.com/jxhkwhy/articles/200495.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL语句-计算不包含最大值和最值的均?/title><link>http://www.aygfsteel.com/jxhkwhy/articles/200493.html</link><dc:creator>UR?/dc:creator><author>UR?/author><pubDate>Wed, 14 May 2008 13:49:00 GMT</pubDate><guid>http://www.aygfsteel.com/jxhkwhy/articles/200493.html</guid><wfw:comment>http://www.aygfsteel.com/jxhkwhy/comments/200493.html</wfw:comment><comments>http://www.aygfsteel.com/jxhkwhy/articles/200493.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200493.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jxhkwhy/services/trackbacks/200493.html</trackback:ping><description><![CDATA[<p>问题Q计^均数Q但希望排除最大和最|以(希望能)减少数据畸偏造成的媄响。例如,计算除最高和最低工资外的所有职员的q_工资?/p> <p>解决Ҏ</p> <p>MySQL和PostgreSQL</p> <p>使用子查询排除最高和最低|</p> <p>1   select avg(sal)</p> <p>2     from emp</p> <p>3    where sal not in (</p> <p>4       (select min(sal) from emp),</p> <p>5       (select max(sal) from emp)</p> <p>6    )</p> <p>DB2、Oracle和SQL Server</p> <p>使用内联视图及窗口函数MAX OVER和MIN OVERQ生成一个结果集Q可以很ҎC中剔除最大和最|</p> <p>1   select avg(sal)</p> <p>2     from (</p> <p>3   select sal, min(sal)over() min_sal, max(sal)over() max_sal</p> <p>4     from emp</p> <p>5          ) x</p> <p>6    where sal not in (min_sal,max_sal) </p> <p>讨论</p> <p>MySQL和PostgreSQL</p> <p>子查询返回表中的最高工资和最低工资。针对返回的g用NOT INQ就可以从^均g排除最高工资和最低工资。记住,如果存在重复Q多个职员都是最高或最低工资)Q那么他们都会被排除在^均g外。如果只x除一个最高和最低|只需从SUM中减d们,再做除法Q?/p> <p>select (sum(sal)-min(sal)-max(sal))/(count(*)-2) </p> <p>   from emp</p> <p>DB2、Oracle和SQL Server</p> <p>内联视图X返回所有工资,其中包括最高工资和最低工资:</p> <p>select sal, min(sal)over() min_sal, max(sal)over() max_sal</p> <p>   from emp </p> <p>       SAL    MIN_SAL    MAX_SAL</p> <p>--------- --------- ---------</p> <p>       800        800       5000</p> <p>      1600        800       5000</p> <p>      1250        800       5000</p> <p>      2975        800       5000</p> <p>      1250        800       5000</p> <p>      2850        800       5000</p> <p>      2450        800       5000</p> <p>      3000        800       5000</p> <p>      5000        800       5000</p> <p>      1500        800       5000</p> <p>      1100        800       5000</p> <p>       950        800       5000</p> <p>      3000        800       5000</p> <p>      1300        800       5000</p> <p>从每一行都可以讉K最高工资和最低工资,因此Q要扑և哪些工资是最高工资的?或最低工资的非常单。外层查询会对内联视图Xq回的行作筛选,q样Q所有与MIN_SAL和MAX_SALAN相匹配的行都会从q_g排除掉?/p> <img src ="http://www.aygfsteel.com/jxhkwhy/aggbug/200493.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jxhkwhy/" target="_blank">UR?/a> 2008-05-14 21:49 <a href="http://www.aygfsteel.com/jxhkwhy/articles/200493.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL语句-对可I列作聚?/title><link>http://www.aygfsteel.com/jxhkwhy/articles/200491.html</link><dc:creator>UR?/dc:creator><author>UR?/author><pubDate>Wed, 14 May 2008 13:47:00 GMT</pubDate><guid>http://www.aygfsteel.com/jxhkwhy/articles/200491.html</guid><wfw:comment>http://www.aygfsteel.com/jxhkwhy/comments/200491.html</wfw:comment><comments>http://www.aygfsteel.com/jxhkwhy/articles/200491.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200491.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jxhkwhy/services/trackbacks/200491.html</trackback:ping><description><![CDATA[<p>问题:Ҏ列进行聚集运,但该列的值可为空Q由于函C忽略NULL|能否保持聚集q算的准性o人担忧。例如,惌求DEPTNO 30中职员的q_佣金Q但有些职员不挣佣金Q这些职员的COMMgؓNULLQ。由于聚集运会忽略NULLQ因此输出结果的准确性没有保障。在q行聚集q算时有时可能需要以某种方式NULL值包括进来?/p> <p>解决Ҏ</p> <p>使用COALESCE函数把NULL转换?Q这样在q行聚集时可以把它们包括q来Q?/p> <p>1   select avg(coalesce(comm,0)) as avg_comm</p> <p>2     from emp</p> <p>3    where deptno=30</p> <p>讨论</p> <p>请务必记住,在用聚集函数时会忽略NULL。不使用COALESCE函数时该解决Ҏ的输出如下:</p> <p>select avg(comm) </p> <p>   from emp </p> <p>where deptno=30 </p> <p>AVG(COMM)</p> <p>---------</p> <p>       550</p> <p>该查询表明,DEPTNO 30的^均䄦金是550Q快速检查这些行如下Q?/p> <p>select ename, comm </p> <p>   from emp </p> <p>where deptno=30 </p> <p>order by comm desc </p> <p>ENAME            COMM</p> <p>---------- ---------</p> <p>BLAKE</p> <p>JAMES</p> <p>MARTIN           1400</p> <p>WARD              500</p> <p>ALLEN             300</p> <p>TURNER              0</p> <p>q表明六个职员中只有四个职员挣得佣金。DEPTNO 30中所有䄦金的d?200Q其q_值应该是2200/6Q而不?200/4。如果不用COALESCE函数Q回{的是问?#8220;DEPTNO 30中挣得䄦金的职员的^均䄦金是多少Q?#8221;Q而不?#8220;DEPTNO 30中所有职员的q_佣金是多?”。用聚集时C要相应处理NULL倹{?/p> <img src ="http://www.aygfsteel.com/jxhkwhy/aggbug/200491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jxhkwhy/" target="_blank">UR?/a> 2008-05-14 21:47 <a href="http://www.aygfsteel.com/jxhkwhy/articles/200491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL语句-求d的百分比http://www.aygfsteel.com/jxhkwhy/articles/200490.htmlUR?/dc:creator>UR?/author>Wed, 14 May 2008 13:46:00 GMThttp://www.aygfsteel.com/jxhkwhy/articles/200490.htmlhttp://www.aygfsteel.com/jxhkwhy/comments/200490.htmlhttp://www.aygfsteel.com/jxhkwhy/articles/200490.html#Feedback0http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200490.htmlhttp://www.aygfsteel.com/jxhkwhy/services/trackbacks/200490.html问题:求特定列中的值占d的百分比。例如,定所有DEPTNO 10工资占d资的癑ֈ比(DEPTNO 10的工资在d资中的百分比敎ͼ?/p>

解决Ҏ

ȝ来说Q在SQL中计占L的百分比跟书面计一P先除后乘。这个例子要计算表EMP中DEPTNO 10工资所占的癑ֈ比。首先,出DEPTNO 10的工资,然后除以表中的工资dQ最后一步,乘以100Q则q回一个表C百分比的倹{?/p>

MySQL和PostgreSQL

DEPTNO 10的工资d除以所有工资dQ?/p>

1 select (sum(

2           case when deptno = 10 then sal end)/sum(sal)

3          )*100 as pct

4    from emp

DB2、Oracle和SQL Server

使用内联视图及窗口函数SUM OVERQ计出所有工资d以及DEPTNO 10的工资和。然后,在外层查询中q行除法和乘法操作:

1   select distinct (d10/total)*100 as pct

2     from (

3   select deptno,

4          sum(sal)over() total,

5          sum(sal)over(partition by deptno) d10

6     from emp

7          ) x

8    where deptno=10

讨论

MySQL和PostgreSQL

用CASE语句能够L地得到DEPTNO 10的工资。然后将它们加v来,q以所有工资d。由于聚集时会忽略NULL|所以CASE语句中不必加入ELSE子句。如果想看到切的被除数和除敎ͼ则可以执行不做除法的查询Q?/p>

select sum(case when deptno = 10 then sal end) as d10,

        sum(sal)

   from emp

D10   SUM(SAL)

---- ---------

8750               29025

依定义SAL的方式不同,在进行除法操作时可能需要做昑ּcd转换。例如,在DB2、SQL Server和PostgreSQL中,如果SAL定义为整敎ͼ则可以把它{换ؓ数Q以便得到正答案,如下所C:

select (cast(

          sum(case when deptno = 10 then sal end)

              as decimal)/sum(sal)

         )*100 as pct

   from emp

DB2、Oracle和SQL Server

除传l解x案外Q该Ҏ使用H口函数计算相对于L的百分数。对于DB2和SQL ServerQ如果SAL定义为整数类型,则在除法操作之前Q需要进行类型{换:

select distinct

        cast(d10 as decimal)/total*100 as pct

   from (

select deptno,

        sum(sal)over() total,

        sum(sal)over(partition by deptno) d10

   from emp

        ) x

where deptno=10

必须CQ窗口函数在WHERE子句后执行。因此不能把针对DEPTNO的筛选放在内联视图X中。分别考虑一下内联视图X中包含及不包含DEPTNO{选的l果。首先,看一下不包含DEPTNO{选的l果Q?/p>

select deptno,

        sum(sal)over() total,

        sum(sal)over(partition by deptno) d10

   from emp

DEP

------- --------- ---------

      10      29025       8750

      10      29025       8750

      10      29025       8750

      20      29025      10875

      20      29025      10875

      20      29025      10875

      20      29025      10875

      20      29025      10875

      30      29025       9400

      30      29025       9400

      30      29025       9400

      30      29025       9400

      30      29025       9400

      30      29025       9400

包含DEPTNO{选的l果Q?/p>

select deptno,

        sum(sal)over() total,

        sum(sal)over(partition by deptno) d10

   from emp

where deptno=10

DEPTNO      TOTAL        D10

------ --------- ---------

     10       8750       8750

     10       8750       8750

     10       8750       8750

׃H口函数在WHERE子句后执行,因此TOTAL的g表示DEPTNO 10的工资之和,而实际上需要用TOTAL表示所有工资的d。这是必须把针对DEPTNO的筛选放在内联视图X外面的原因?/p>

]]>
SQL语句-计算中间?/title><link>http://www.aygfsteel.com/jxhkwhy/articles/200489.html</link><dc:creator>UR?/dc:creator><author>UR?/author><pubDate>Wed, 14 May 2008 13:45:00 GMT</pubDate><guid>http://www.aygfsteel.com/jxhkwhy/articles/200489.html</guid><wfw:comment>http://www.aygfsteel.com/jxhkwhy/comments/200489.html</wfw:comment><comments>http://www.aygfsteel.com/jxhkwhy/articles/200489.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200489.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jxhkwhy/services/trackbacks/200489.html</trackback:ping><description><![CDATA[<p>问题:计算一列数字值的中间|中间值就是一l有序元素中间成员的|。例如,查找DEPTNO 20中工资的中间数。如下列工资Q?/p> <p>select sal </p> <p>   from emp </p> <p>where deptno = 20 </p> <p>order by sal </p> <p>        SAL</p> <p>----------</p> <p>        800</p> <p>       1100</p> <p>       2975</p> <p>       3000</p> <p>       3000</p> <p>中间Cؓ2975?/p> <p>解决Ҏ</p> <p>除了Oracle解决ҎQ用函数计算中间敎ͼ之外Q其他所有解x案都是以Rozenshtein、Abramovich和Birger在Optimizing Transact-SQL: Advanced Programming Techniques (SQL Forum Press, 1997)中描q的Ҏ为基的。与传统的自联接相比Q窗口函数的引入Q解决Ҏ更ؓ有效?/p> <p>DB2 </p> <p>使用H口函数COUNT(*) OVER和ROW_NUMBERQ查找中间数Q?/p> <p>1   select avg(sal)</p> <p>2     from (</p> <p>3   select sal,</p> <p>4          count(*) over() total,</p> <p>5          cast(count(*) over() as decimal)/2 mid,</p> <p>6          ceil(cast(count(*) over() as decimal)/2) next,</p> <p>7          row_number() over (order by sal) rn</p> <p>8     from emp</p> <p>9    where deptno = 20</p> <p>10          ) x</p> <p>11    where ( mod(total,2) = 0</p> <p>12            and rn in ( mid, mid+1 )</p> <p>13          )</p> <p>14       or ( mod(total,2) = 1</p> <p>15            and rn = next</p> <p>16          )</p> <p>MySQL和PostgreSQL</p> <p>使用自联接查找中间数Q?/p> <p>1   select avg(sal)</p> <p>2     from (</p> <p>3   select e.sal</p> <p>4     from emp e, emp d</p> <p>5    where e.deptno = d.deptno</p> <p>6      and e.deptno = 20</p> <p>7    group by e.sal</p> <p>8   having sum(case when e.sal = d.sal then 1 else 0 end) </p> <p>9                             >= abs(sum(sign(e.sal - d.sal)))</p> <p>10          )</p> <p>Oracle</p> <p>使用函数MEDIANQOracle Database 10gQ或PERCENTILE_CONTQOracle9i DatabaseQ:</p> <p>1 select median (sal) </p> <p>2    from emp </p> <p>3   where deptno=20 </p> <p>1 select percentile_cont(0.5)</p> <p>2          within group(order by sal) </p> <p>3    from emp </p> <p>4   where deptno=20</p> <p>对于Oracle8i DatabaseQ用DB2解决Ҏ。对于Oracle8i Database之前的版本,可以采用PostgreSQL/MySQL解决Ҏ?/p> <p>SQL Server</p> <p>使用H口函数COUNT(*) OVER和ROW_NUMBERQ可得到中间敎ͼ</p> <p>1   select avg(sal)</p> <p>2     from (</p> <p>3   select sal,</p> <p>4          count(*)over() total,</p> <p>5          cast(count(*)over() as decimal)/2 mid,</p> <p>6          ceiling(cast(count(*)over() as decimal)/2) next,</p> <p>7          row_number()over(order by sal) rn</p> <p>8     from emp</p> <p>9    where deptno = 20</p> <p>10          ) x</p> <p>11    where ( total%2 = 0</p> <p>12            and rn in ( mid, mid+1 )</p> <p>13          )</p> <p>14       or ( total%2 = 1</p> <p>15            and rn = next</p> <p>16          )</p> <p>讨论</p> <p>DB2和SQL Server</p> <p>DB2和SQL Server 解决Ҏ的唯一差别是语法的E许不同QSQL Server?#8220;%”求模Q而DB2使用MOD函数Q其余的都相同。内联视图Xq回三个不同的计数|TOTAL、MID和NEXTQ还用到由ROW_NUMBER生成的RN。这些附加列有助于求解中间数。检验内联视图X的结果集Q就会看到这些列表示的意义:</p> <p>select sal,</p> <p>        count(*)over() total,</p> <p>        cast(count(*)over() as decimal)/2 mid,</p> <p>        ceil(cast(count(*)over() as decimal)/2) next,</p> <p>        row_number()over(order by sal) rn</p> <p>   from emp</p> <p>where deptno = 20 </p> <p>SAL TOTAL   MID NEXT    RN</p> <p>---- ----- ---- ---- ----</p> <p>800      5   2.5     3     1</p> <p>1100      5   2.5     3     2</p> <p>2975      5   2.5     3     3</p> <p>3000      5   2.5     3     4</p> <p>3000      5   2.5     3     5</p> <p>要得C间数Q一定要把SAL值由低到高排序。由于DEPTNO 20中的职员数是奇数Q因此它的中间数是其RN与NEXT相等的SALQ即大于职员L除以2的最整敎ͼ?/p> <p>如果l果集返回奇数行QWHERE子句的第一部分Q第11?3行)条g不满뀂如果能够确定结果集是奇数行Q则可以化ؓQ?/p> <p>select avg(sal)</p> <p>   from (</p> <p>select sal,</p> <p>        count(*)over() total,</p> <p>        ceil(cast(count(*)over() as decimal)/2) next,</p> <p>        row_number()over(order by sal) rn</p> <p>   from emp</p> <p>where deptno = 20</p> <p>        ) x</p> <p>where rn = next</p> <p>令h遗憾的是Q如果结果集包含偶数行,上述化的解决Ҏp不通。在最初的解决Ҏ中,采用MID列中的值处理偶数行。想想DEPTNO 30的内联视图X的结果会怎样Q该部门?名职员:</p> <p>select sal,</p> <p>        count(*)over() total,</p> <p>        cast(count(*)over() as decimal)/2 mid,</p> <p>        ceil(cast(count(*)over() as decimal)/2) next,</p> <p>        row_number()over(order by sal) rn</p> <p>   from emp</p> <p>where deptno = 30 </p> <p>SAL TOTAL   MID NEXT    RN</p> <p>---- ----- ---- ---- ----</p> <p>950      6     3     3     1</p> <p>1250      6     3     3     2</p> <p>1250      6     3     3     3</p> <p>1500      6     3     3     4</p> <p>1600      6     3     3     5</p> <p>2850      6     3     3     6</p> <p>׃q回了偶数行Q则采用下述方式计算中间敎ͼ计算RN分别{于MID和MID + 1两行的^均数?/p> <p>MySQL和PostgreSQL</p> <p>ҎW一个自联接表EMP计算中间敎ͼ而该表返回了所有工资的W卡儿积QGROUP BY    E.SAL会去掉重复|。HAVING子句使用函数SUM计算E.SAL{于D.SAL的次敎ͼ如果q个值大于等于E.SAL且大于D.SALơ数Q那么该行就是中间数。在SELECT列表中加入SUM可以观察到q种情况Q?/p> <p>select e.sal,</p> <p>        sum(case when e.sal=d.sal </p> <p>                 then 1 else 0 end) as cnt1,</p> <p>        abs(sum(sign(e.sal - d.sal))) as cnt2</p> <p>   from emp e, emp d</p> <p>where e.deptno = d.deptno</p> <p>    and e.deptno = 20</p> <p>group by e.sal </p> <p>SAL CNT1 CNT2</p> <p>---- ---- ----</p> <p>800     1     4</p> <p>1100     1     2</p> <p>2975     1     0</p> <p>3000     4     6</p> <p>Oracle</p> <p>在Oracle Database 10g或Oracle9i Database中,可以使用Oracle提供的函数计中间数Q对于Oracle8i DatabaseQ可以采用DB2解决ҎQ其他版本必采用PostgreSQL解决Ҏ。显然可以用MEDIAN函数计算中间|用PERCENTILE_CONT函数也可以计中间值就不那么显而易见了。传递给PERCENTILE_CONT的?.5是一个百分比倹{子句WITHIN GROUP (ORDER BY SAL)定PERCENTILE_CONT要搜索哪些有序行Q记住,中间值就是一l已排序值的中间|。返回的值就是搜索的有序行中W合l定癑ֈ比(在这个例子中?.5Q因为其两个边界值分别ؓ0?Q的倹{?/p> <img src ="http://www.aygfsteel.com/jxhkwhy/aggbug/200489.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jxhkwhy/" target="_blank">UR?/a> 2008-05-14 21:45 <a href="http://www.aygfsteel.com/jxhkwhy/articles/200489.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL语句-计算模式http://www.aygfsteel.com/jxhkwhy/articles/200486.htmlUR?/dc:creator>UR?/author>Wed, 14 May 2008 13:44:00 GMThttp://www.aygfsteel.com/jxhkwhy/articles/200486.htmlhttp://www.aygfsteel.com/jxhkwhy/comments/200486.htmlhttp://www.aygfsteel.com/jxhkwhy/articles/200486.html#Feedback0http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200486.htmlhttp://www.aygfsteel.com/jxhkwhy/services/trackbacks/200486.html问题:查找某个列中值的模式Q数学中的模式概念就是对于给定的数据集出现最频繁的元素)。例如,查找DEPTNO 20中工资的模式。例如下列工资:

select sal

   from emp

where deptno = 20

order by sal

        SAL

----------

        800

       1100

       2975

       3000

       3000

the mode is 3000.

解决Ҏ

DB2和SQL Server

使用H口函数DENSE_RANKQ把工资重复出现ơ数分等U,以便提取模式Q?/p>

1   select sal

2     from (

3   select sal,

4          dense_rank()over(order by cnt desc) as rnk

5     from (

6   select sal, count(*) as cnt

8     from emp

9    where deptno = 20

10    group by sal

11          ) x

12          ) y

13    where rnk = 1

Oracle

在Oracle8i Database中,可以使用DB2l出的解x案。对于Oracle9i及更高版本,可以用聚集函数MAX的KEEP扩展Q以得到SAL模式。特别要注意的是Q如果存在绑带,也即多个行都是模式,则采用KEEPҎ仅能得到一个,卛_中工资最高的那个。如果想要看所有模式(如果存在多个模式Q,则必M改该ҎQ或者简单地使用前面介绍的DB2解决Ҏ。在q个例子中,׃3000是DEPTNO 20中SAL的模式,而且它也是最高的SALQ因此以下方案就可以了:

1   select max(sal)

2           keep(dense_rank first order by cnt desc) sal

3     from (

4   select sal, count(*) cnt

5     from emp

6    where deptno=20

7    group by sal

8          )

MySQL和PostgreSQL

使用子查询查找模式:

1   select sal

2     from emp

3    where deptno = 20

4    group by sal

5   having count(*) >= all ( select count(*)  

6                              from emp

7                             where deptno = 20

8                             group by sal )

讨论

DB2和SQL Server

内联视图X返回每个SAL及它出现的次数。内联视图Y使用H口函数DENSE_RANKQ它允许l带Q给l果排序。结果按每个SAL出现的次数分{Q如下所C:

1 select sal,

2         dense_rank()over(order by cnt desc) as rnk

3    from (

4 select sal,count(*) as cnt

5    from emp

6   where deptno = 20

7   group by sal

8         ) x

   SAL         RNK

----- ----------

3000           1

   800           2

1100           2

2975           2

最外层的查询只单地保留RNK?的行?/p>

Oracle

内联视图返回所有SAL及其出现的次敎ͼ如下所C:

select sal, count(*) cnt

   from emp

where deptno=20

group by sal

   SAL         CNT

----- ----------

   800           1

1100           1

2975           1

3000           2

下一步,使用聚集函数MAX的KEEP扩展查找模式。如果仔l分析下面给出的KEEP子句Q会发现它又有三个子句,即DENSE_RANK、FIRST和ORDER BY CNT DESCQ?/p>

keep(dense_rank first order by cnt desc)

q种做法Ҏ模式极其方便。KEEP子句Ҏ内联视图q回的CNT值来定MAXq回SAL的哪个倹{按从右向左的方向将CNT递减排序Q然后保留下按DENSE_RANKơ序q回的所有CNT值的W一个倹{查看一下内联视囄l果集,׃看到3000h最高的CNT?—?2。MAX(SAL) q回的是拥有最高CNT值的最大SALQ在本例中是3000?/p>

有关Oracle中集合函数的KEEP扩展的深入讨论,请参阅第11章第11.11节。有关Oracle中集合函数的KEEP扩展的深入讨论,请参阅第11章第11.11节?/p>

MySQL和PostgreSQL

子查询将q回每个SAL出现的次数。外层查询将q回其的出现ơ数大于{于子查询所q回所有计数值的SALQ换句话_外层查询会返回DEPTNO 20中出现最多的工资Q?/p>

]]>
SQL语句-计算累计?/title><link>http://www.aygfsteel.com/jxhkwhy/articles/200484.html</link><dc:creator>UR?/dc:creator><author>UR?/author><pubDate>Wed, 14 May 2008 13:42:00 GMT</pubDate><guid>http://www.aygfsteel.com/jxhkwhy/articles/200484.html</guid><wfw:comment>http://www.aygfsteel.com/jxhkwhy/comments/200484.html</wfw:comment><comments>http://www.aygfsteel.com/jxhkwhy/articles/200484.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200484.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jxhkwhy/services/trackbacks/200484.html</trackback:ping><description><![CDATA[<p>问题Q对于数字列中的|计算其篏计差。例如,计算DEPTNO 10中工资的累计差。要q回下列l果集:</p> <p>ENAME              SAL RUNNING_DIFF</p> <p>---------- ---------- ------------</p> <p>MILLER            1300          1300</p> <p>CLARK             2450         -1150</p> <p>KING              5000         -6150</p> <p>解决Ҏ</p> <p>DB2和Oracle </p> <p>使用H口函数SUM OVER创徏累计差:</p> <p>1   select ename,sal,</p> <p>2          sum(case when rn = 1 then sal else -sal end) </p> <p>3           over(order by sal,empno) as running_diff<>5   select empno,ename,sal,</p> <p>6          row_number()over(order by sal,empno) as rn</p> <p>7     from emp </p> <p>8    where deptno = 10</p> <p>9          ) x</p> <p>MySQL、PostgreSQL和SQL Server</p> <p>使用标量子查询计篏计差Q?/p> <p>1 select a.empno, a.ename, a.sal,</p> <p>2         (select case when a.empno = min(b.empno) then sum(b.sal) </p> <p>3                      else sum(-b.sal) </p> <p>4                 end</p> <p>5            from emp b</p> <p>6           where b.empno <= a.empno</p> <p>7             and b.deptno = a.deptno ) as rnk</p> <p>8    from emp a</p> <p>9   where a.deptno = 10</p> <p>讨论</p> <p>该解x案与“生成累计?#8221;一节介l的解决Ҏ大致相同。唯一的差别是QSAL除了W一个|因ؓ要从DEPTNO 10的SAL开始)之外Q其余所有值都q回负倹{?/p> <img src ="http://www.aygfsteel.com/jxhkwhy/aggbug/200484.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jxhkwhy/" target="_blank">UR?/a> 2008-05-14 21:42 <a href="http://www.aygfsteel.com/jxhkwhy/articles/200484.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL语句-计算累积?/title><link>http://www.aygfsteel.com/jxhkwhy/articles/200483.html</link><dc:creator>UR?/dc:creator><author>UR?/author><pubDate>Wed, 14 May 2008 13:40:00 GMT</pubDate><guid>http://www.aygfsteel.com/jxhkwhy/articles/200483.html</guid><wfw:comment>http://www.aygfsteel.com/jxhkwhy/comments/200483.html</wfw:comment><comments>http://www.aygfsteel.com/jxhkwhy/articles/200483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200483.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jxhkwhy/services/trackbacks/200483.html</trackback:ping><description><![CDATA[<p>问题Q计某个数字列的篏乘积。其操作方式?#8220;计算累计?#8221;怼Q只是用乘法而不是加法?/p> <p>解决Ҏ</p> <p>作ؓ例子Q本解决Ҏ中都计算职员工资的篏乘积。虽然工资的累乘U没有多大用处,然而可以很Ҏ地把该技巧用于其他更有用的领域?/p> <p>DB2和Oracle </p> <p>使用H口函数SUM OVERQ用Ҏ相加来模拟乘法操作: </p> <p>1 select empno,ename,sal,</p> <p>2         exp(sum(ln(sal))over(order by sal,empno)) as running_prod</p> <p>3    from emp</p> <p>4   where deptno = 10 </p> <p>EMPNO ENAME        SAL          RUNNING_PROD</p> <p>----- ---------- ---- --------------------</p> <p>7934 MILLER      1300                  1300</p> <p>7782 CLARK       2450               3185000</p> <p>7839 KING        5000           15925000000</p> <p>在SQL中,对小于等?的值取Ҏ是无效的。如果表中包含这L|一定要避免把这些无效的g递给SQL的LN函数。ؓ了增加可L,该解x案ƈ没有Ҏ效值和NULL值采取防范措施,但自q写代码时Q一定要考虑是否需要这U预阌Ӏ如果一定要用到负值和0|那么q种解决Ҏ不合适?/p> <p>Oracle独有的另一U解x案是使用Oracle Database 10g新引入的MODEL子句。在下面的例子中Q每个SAL都是负数Q这表明累乘U允许出现负|</p> <p>1 select empno, ename, sal, tmp as running_prod</p> <p>2    from (</p> <p>3 select empno,ename,-sal as sal</p> <p>4    from emp</p> <p>5   where deptno=10</p> <p>6         )</p> <p>7   model</p> <p>8     dimension by(row_number()over(order by sal desc) rn )</p> <p>9     measures(sal, 0 tmp, empno, ename)</p> <p>10    rules (</p> <p>11      tmp[any] = case when sal[cv()-1] is null then sal[cv()] </p> <p>12                      else tmp[cv()-1]*sal[cv()] </p> <p>13                 end</p> <p>14    ) </p> <p>EMPNO ENAME        SAL          RUNNING_PROD</p> <p>----- ---------- ---- --------------------</p> <p>7934 MILLER      -1300                -1300</p> <p>7782 CLARK       -2450              3185000</p> <p>7839 KING        -5000         -15925000000</p> <p>MySQL、PostgreSQL和SQL Server</p> <p>q可以用对数相加的ҎQ但q些q_q不支持H口函数Q因此用标量子查询取而代之: </p> <p>1 select e.empno,e.ename,e.sal,</p> <p>2         (select exp(sum(ln(d.sal))) </p> <p>3            from emp d </p> <p>4           where d.empno <= e.empno </p> <p>5             and e.deptno=d.deptno) as running_prod </p> <p>6   from emp e </p> <p>7   where e.deptno=10 </p> <p>EMPNO ENAME        SAL          RUNNING_PROD</p> <p>----- ---------- ---- --------------------</p> <p>7782 CLARK       2450                  2450</p> <p>7839 KING        5000              12250000</p> <p>7934 MILLER      1300           15925000000</p> <p>SQL Server用户使用LOG代替LN?/p> <p>讨论</p> <p>除了MODEL子句ҎQ仅对Oracle Database 10g或更高版本可用)之外Q所有解x案都利用了乘法运的Ҏ,按下列步骤用加法q行计算Q?/p> <p>1.     计算各自的自然对?/p> <p>2.     计算q些Ҏ的和</p> <p>3.     对结果进行数学常量e的幂q算Q用EXP函数Q?/p> <p>当采用这U方法时Q需要注意,对于0值和负|q种Ҏ不可行,因ؓM于{于0的值都出了SQLҎ的定义域?/p> <p>DB2和Oracle </p> <p>有关H口函数SUM OVER的功能,请参?#8220;生成累计?#8221;一节?/p> <p>对于Oracle Database 10g或更高版本,可以使用MODEL子句生成累乘U。同时用MODEL子句及窗口函数ROW_NUMBERQ很Ҏp讉K前面的行。可以像讉K数组一栯问MEASURES列表中的每一V然后,可以使用DIMENSIONS列表中的(由ROW_NUMBERq回的|别名RNQ搜索该数组Q?/p> <p>select empno, ename, sal, tmp as running_prod,rn</p> <p>   from (</p> <p>select empno,ename,-sal as sal</p> <p>   from emp</p> <p>where deptno=10</p> <p>        )</p> <p>model</p> <p>    dimension by(row_number()over(order by sal desc) rn )</p> <p>    measures(sal, 0 tmp, empno, ename)</p> <p>   rules () </p> <p>EMPNO ENAME              SAL RUNNING_PROD          RN</p> <p>----- ---------- ---------- ------------ ----------</p> <p>7934 MILLER           -1300             0           1</p> <p>7782 CLARK            -2450             0           2</p> <p>7839 KING             -5000             0           3</p> <p>观察一下,会发现SAL[1]的gؓQ?300。由于数字逐一q箋递增、没有间隙,所以可以通过?来引用前一行。RULES子句如下Q?/p> <p>rules (</p> <p>    tmp[any] = case when   sal[cv()-1] is null then sal[cv()] </p> <p>                    else tmp[cv()-1]*sal[cv()] </p> <p>               end</p> <p>)</p> <p>它用内|操作符ANY处理每一行,而ƈ未进行硬~码。这个例子中ANY的值分别ؓ1??。把TMP[n]初始化ؓ0。通过计算相应SAL行的当前|函数CVq回当前|Q可以给TMP[n]指定一个倹{把TMP[1]初始化ؓ0Q把SAL[1]初始化ؓQ?300。SAL[0]没有|所以把TMP[1]讄为SAL[1]。在讄了TMP[1]之后Q下一行就是TMP[2]。计第一个SAL[1]Q由于ANY的当前值是2Q因此SAL[CV()Q?]的值是SAL[1]Q。SAL[1]不ؓI,而且{于Q?300Q因此把TMP[2]讄为TMP[1]和SAL[2]的乘U。所有行都进行上q操作?/p> <p>MySQL、PostgreSQL和SQL Server</p> <p>有关MySQL、PostgreSQL和SQL Server解决Ҏ所采用的子查询Ҏ的说明,请参阅本章第7.6节?/p> <p>要注意,Z子查询解x案的输出与Oracle和DB2解决Ҏ的输出有许差别Q其原因来自EMPNO比较Q它们按不同的顺序计篏乘积Q。与累计和一P其L也是由标量子查询的谓词驱动的Q在该解x案中Q行是按EMPNO排序的,而对于Oracle/DB2 解决ҎQ行是按SAL排序的?/p> <img src ="http://www.aygfsteel.com/jxhkwhy/aggbug/200483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jxhkwhy/" target="_blank">UR?/a> 2008-05-14 21:40 <a href="http://www.aygfsteel.com/jxhkwhy/articles/200483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL语句-计算累加?/title><link>http://www.aygfsteel.com/jxhkwhy/articles/200482.html</link><dc:creator>UR?/dc:creator><author>UR?/author><pubDate>Wed, 14 May 2008 13:37:00 GMT</pubDate><guid>http://www.aygfsteel.com/jxhkwhy/articles/200482.html</guid><wfw:comment>http://www.aygfsteel.com/jxhkwhy/comments/200482.html</wfw:comment><comments>http://www.aygfsteel.com/jxhkwhy/articles/200482.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jxhkwhy/comments/commentRss/200482.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jxhkwhy/services/trackbacks/200482.html</trackback:ping><description><![CDATA[<p>问题Q计某个列中所有值的累计?/p> <p>解决Ҏ</p> <p>下面l出了一U解x案,它展CZ如何计算所有职员工资的累计和。ؓ增加可读性,其结果是按SAL排序的,q样p够很Ҏ地观察到累计和变化的q程?/p> <p>DB2和Oracle </p> <p>使用H口版本的SUM函数计算累计和:</p> <p>1 select ename, sal, </p> <p>2         sum(sal) over (order by sal,empno) as running_total </p> <p>3    from emp </p> <p>4    order by 2 </p> <p>ENAME              SAL RUNNING_TOTAL</p> <p>---------- ---------- -------------</p> <p>SMITH              800            800</p> <p>JAMES              950           1750</p> <p>ADAMS             1100           2850</p> <p>WARD              1250           4100</p> <p>MARTIN            1250           5350</p> <p>MILLER            1300           6650</p> <p>TURNER            1500           8150</p> <p>ALLEN             1600           9750</p> <p>CLARK             2450          12200</p> <p>BLAKE             2850          15050</p> <p>JONES             2975          18025</p> <p>SCOTT             3000          21025</p> <p>FORD              3000          24025</p> <p>KING              5000          29025</p> <p>MySQL、PostgreSQL和SQL Server</p> <p>使用标量子查询计篏计和Q由于不使用SUM OVERq类H口函数Q因此就不能像在DB2和Oracle解决Ҏ中那样容易地按SALl结果排序)。不怎么_累计和是正确的(最l结果与上一节相同)Q但׃没有q行排序Q其中间值有所不同Q?/p> <p>1 select e.ename, e.sal,</p> <p>2         (select sum(d.sal) from emp d </p> <p>3           where d.empno <= e.empno) as running_total</p> <p>4    from emp e</p> <p>5   order by 3 </p> <p>ENAME              SAL RUNNING_TOTAL</p> <p>---------- ---------- -------------</p> <p>SMITH              800            800</p> <p>ALLEN             1600           2400</p> <p>WARD              1250           3650</p> <p>JONES             2975           6625</p> <p>MARTIN            1250           7875</p> <p>BLAKE             2850          10725</p> <p>CLARK             2450          13175</p> <p>SCOTT             3000          16175</p> <p>KING              5000          21175</p> <p>TURNER            1500          22675</p> <p>ADAMS             1100          23775</p> <p>JAMES              950          24725</p> <p>FORD              3000          27725</p> <p>MILLER            1300          29025</p> <p>讨论</p> <p>生成累计和是因用新的ANSIH口函数而得以简化的d之一。对于不支持q些H口函数的DBMSQ需要用标量子查询Q按取值唯一的字D联接)?/p> <p>DB2和Oracle </p> <p>H口函数SUM OVER能够非常Ҏ地生成篏计和。该解决Ҏ中的ORDER BY子句不仅包含SAL列,而且q包含EMPNO列(主键Q,以避免篏计和中出现重复倹{下面例子中的RUNNING_TOTAL2列示意了存在重复值时可能带来的问题:</p> <p>select empno, sal, </p> <p>        sum(sal)over(order by sal,empno) as running_total1,</p> <p>        sum(sal)over(order by sal) as running_total2</p> <p>   from emp </p> <p>order by 2 </p> <p>ENAME              SAL RUNNING_TOTAL1 RUNNING_TOTAL2</p> <p>---------- ---------- -------------- --------------</p> <p>SMITH              800             800             800</p> <p>JAMES              950            1750            1750</p> <p>ADAMS             1100            2850            2850</p> <p>WARD              1250            4100            5350</p> <p>MARTIN            1250            5350            5350</p> <p>MILLER            1300            6650            6650</p> <p>TURNER            1500            8150            8150</p> <p>ALLEN             1600            9750            9750</p> <p>CLARK             2450           12200           12200</p> <p>BLAKE             2850           15050           15050</p> <p>JONES             2975           18025           18025</p> <p>SCOTT             3000           21025           24025</p> <p>FORD              3000           24025           24025</p> <p>KING              5000           29025           29025</p> <p>对于WARD、MARTIN、SCOTT和FORDQRUNNING_TOTAL2中的值都不正。他们的工资分别出现了多ơ,q些重复值都被加在一赯入篏计和。这是需要用EMPNOQ它是唯一的)才能生成与RUNNING_TOTAL1一LQ正)l果的原因。大家想一惻I对于ADAMSQRUNNING_TOTAL1的gؓ2850QRUNNING_TOTAL2把WARD的工?250?850相加Q应该得?100Q然而,RUNNING_TOTAL2却返回了5350Q这是ؓ什么呢Q因为WARD和MARTIN的SAL相同Q他们两个的工资Q?250Q加在一起就{于2500Q然后再?850Q就得到5350。如果指定按不会有重复值的列组合(例如QSAL和EMPNO的取值组合都是唯一的)排序Q就能确保生成正的累计和?/p> <p>MySQL、PostgreSQL和SQL Server</p> <p>在这些DBMS完全支持H口函数之前Q可以用标量子查询计算累计和。一定要按取值唯一的列联接Q否则一旦存在像工资重复q样的情况,׃产生不正的累计和。本节解x案的关键是把D.EMPNO与E.EMPNO联接hQ它会返回(求和Q每个满D.EMPNO于或等于E.EMPNO D.SAL。ؓ了更Ҏ理解q些内容Q可以重新编写标量子查询Q把它写成职员之间的联接Q?/p> <p>select e.ename as ename1, e.empno as empno1, e.sal as sal1,</p> <p>        d.ename as ename2, d.empno as empno2, d.sal as sal2</p> <p>   from emp e, emp d</p> <p>where d.empno <= e.empno</p> <p>    and e.empno = 7566 </p> <p>ENAME           EMPNO1        SAL1 ENAME           EMPNO2        SAL2</p> <p>---------- ---------- ---------- ---------- ---------- ----------</p> <p>JONES             7566        2975 SMITH             7369         800</p> <p>JONES             7566        2975 ALLEN             7499        1600</p> <p>JONES             7566        2975 WARD              7521        1250</p> <p>JONES             7566        2975 JONES             7566        2975</p> <p>EMPNO2中的每个gEMPNO1中的每个值相比较。对于EMPNO2值小于等于EMPNO1值的所有行Q都会把SAL2值加入d。在q个例子中,职员Smith、Allen、Ward和Jones的EMPNO值都与Jones的EMPNO值相比较。由于这四个职员的EMPNO都满_于等于Jones的EMPNO的条Ӟ所以会把这些工资加hQ而那些大于Jones的EMPNO的职员都不会计入SUM中。完整的查询的计方法是Q将所有EMPNO于{于7934QMiller的EMPNOQ这个表中的最大|的所有职员的工资加v来?/p> <img src ="http://www.aygfsteel.com/jxhkwhy/aggbug/200482.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jxhkwhy/" target="_blank">UR?/a> 2008-05-14 21:37 <a href="http://www.aygfsteel.com/jxhkwhy/articles/200482.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̫</a>| <a href="http://" target="_blank">ƽң</a>| <a href="http://" target="_blank">μ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƺ</a>| <a href="http://" target="_blank">˶</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͨ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ϸ</a>| <a href="http://" target="_blank">ˮ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ӳ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ϲ</a>| <a href="http://" target="_blank">ݰ</a>| <a href="http://" target="_blank">Ǽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank">̩</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">˳</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>