SlideShare a Scribd company logo
1 of 17
Sql 常见面试题(总结)

1.用一条 SQL 语句 查询出每门课都大于 80 分的学生姓名



name                     kecheng                          fenshu

张          三                           语              文                        81

张          三                           数              学                        75

李          四                           语              文                        76

李          四                           数              学                        90

王          五                           语              文                        81

王         五                            数              学                        100

王          五                           英              语                        90



A: select distinct name from table     where    name not in (select distinct name

from                 table                      where                  fenshu<=80)



2.        学          生             表                       如           下         :

自 动 编 号           学 号            姓 名       课 程 编 号           课 程 名 称        分 数

1          2005001           张     三           0001            数   学            69

2          2005002           李     四           0001            数   学            89

3          2005001           张     三           0001            数   学            69

删 除 除 了 自 动 编 号 不 同 , 其 他 都 相 同 的 学 生 冗 余 信 息



A: delete tablename where 自动编号 not in(select min(自动编号) from tablename

group by 学号,姓名,课程编号,课程名称,分数)



一个叫 department 的表,里面只有一个字段 name,一共有 4 条纪录,分别是 a,b,c,d,对应
四 个 球 对 , 现 在 四 个 球 对 进 行 比 赛 , 用 一 条 sql 语 句 显 示 所 有 可 能 的 比 赛 组 合 .
你先按你自己的想法做一下,看结果有我的这个简单吗?
答            :        select         a.name,         b.name
from             team        a,            team          b
where a.name < b.name
请用 SQL 语句实现:从 TestDB 数据表中查询出所有月份的发生额都比 101 科目相应月份的
发 生 额 高 的 科 目 。 请 注 意 : TestDB 中 有 很 多 科 目 , 都 有 1 - 12 月 份 的 发 生 额 。
AccID : 科 目 代 码 , Occmonth : 发 生 额 月 份 , DebitOccur : 发 生 额 。
数据库名:JcyAudit,数据集:Select * from TestDB
答                        :                     select                       a.*
from                        TestDB                      a
,(select Occmonth,max(DebitOccur) Debit101ccur from TestDB where AccID='101'
group                      by                    Occmonth)                    b
where a.Occmonth=b.Occmonth and a.DebitOccur>b.Debit101ccur
*******************************************************************************
*****
面     试      题      :     怎      么     把     这      样      一    个      表     儿
year month                                                               amount
1991                                   1                                    1.1
1991                                   2                                    1.2
1991                                   3                                    1.3
1991                                   4                                    1.4
1992                                   1                                    2.1
1992                                   2                                    2.2
1992                                   3                                    2.3
1992                                   4                                    2.4
查          成           这           样        一           个         结          果
year                                                             m1 m2 m3 m4
1991                 1.1               1.2                1.3               1.4
1992             2.1              2.2           2.3            2.4

答                        案                         一                        、
select                                year,
(select    amount from aaa   m where month=1 and m.year=aaa.year) as m1,
(select    amount from aaa   m where month=2 and m.year=aaa.year) as m2,
(select    amount from aaa   m where month=3 and m.year=aaa.year) as m3,
(select    amount from aaa   m where month=4 and m.year=aaa.year) as m4
from aaa    group by year

这           个          是           ORACLE 中           做           的          :
select    *     from    (select     name,    year    b1,     lead(year)    over
(partition by name order by year) b2, lead(m,2) over(partition by name order by
year)                                                            b3,rank()over(
partition by name order by year) rk from t) where rk=1;
*******************************************************************************
*****
精            妙           的            SQL           语            句           !
精              妙               SQL             语              句
作      者    :       不       详            发      文            时      间         :       2003.05.29           10:55:05

说 明 : 复 制 表 ( 只 复 制 结 构 , 源 表 名 : a                                                                新 表 名 : b)

SQL:        select          *           into             b          from             a        where           1<>1

说 明 : 拷 贝 表 ( 拷 贝 数 据 , 源 表 名 : a                                                            目 标 表 名 : b)

SQL:       insert       into        b(a,            b,         c)           select       d,e,f         from       b;

说      明   :    显       示       文   章       、       提        交      人        和    最      后         回   复      时      间

SQL: select a.title,a.username,b.adddate from table a,(select max(adddate)
adddate     from      table      where     table.title=a.title)    b

说      明   :    外     连     接       查    询      (    表         名        1    :    a          表     名    2     :      b)

SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

说      明       :      日         程       安       排            提          前        五       分         钟    提         醒

SQL: select * from 日 程 安 排 where datediff('minute',f 开 始 时 间 ,getdate())>5

说 明 : 两 张 关 联 表 , 删 除 主 表 中 已 经 在 副 表 中 没 有 的 信 息

SQL:

delete from info where                   not        exists          (       select       *    from     infobz        where
info.infid=infobz.infid                                                         )

说                           明                                :                                --

SQL:

SELECT          A.NUM,              A.NAME,                   B.UPD_DATE,                    B.PREV_UPD_DATE

FROM                                                         TABLE1,

(SELECT            X.NUM,           X.UPD_DATE,                     Y.UPD_DATE                 PREV_UPD_DATE

FROM        (SELECT         NUM,            UPD_DATE,                   INBOUND_QTY,               STOCK_ONHAND

FROM                                                         TABLE2
WHERE     TO_CHAR(UPD_DATE,'YYYY/MM')       =       TO_CHAR(SYSDATE,           'YYYY/MM'))         X,

(SELECT               NUM,              UPD_DATE,                         STOCK_ONHAND

FROM                                        TABLE2

WHERE                   TO_CHAR(UPD_DATE,'YYYY/MM')                               =

TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM')                ¦¦        '/01','YYYY/MM/DD')           -       1,
'YYYY/MM')                      )                                       Y,

WHERE         X.NUM             =       Y.NUM                         (           +       )

AND     X.INBOUND_QTY       +   NVL(Y.STOCK_ONHAND,0)           <>       X.STOCK_ONHAND       )        B

WHERE                   A.NUM                       =                        B.NUM

说                       明                       :                            --

SQL:

select * from studentinfo where not exists(select * from student where
studentinfo.id=student.id) and 系 名 称 ='"&strdepartmentname&"' and 专 业 名 称
='"&strprofessionname&"' order by    性 别 , 生 源 地 , 高 考 总 成 绩

说                               明                                    :

从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源)

SQL:

SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear,

SUM(decode(TO_CHAR(a.telfeedate,         'mm'),         '01',    a.factration))          AS       JAN,

SUM(decode(TO_CHAR(a.telfeedate,         'mm'),         '02',    a.factration))          AS       FRI,

SUM(decode(TO_CHAR(a.telfeedate,         'mm'),         '03',    a.factration))          AS       MAR,

SUM(decode(TO_CHAR(a.telfeedate,         'mm'),         '04',    a.factration))          AS       APR,

SUM(decode(TO_CHAR(a.telfeedate,         'mm'),         '05',    a.factration))          AS       MAY,
SUM(decode(TO_CHAR(a.telfeedate,               'mm'),       '06',     a.factration))         AS       JUE,

SUM(decode(TO_CHAR(a.telfeedate,               'mm'),       '07',     a.factration))         AS       JUL,

SUM(decode(TO_CHAR(a.telfeedate,               'mm'),       '08',     a.factration))         AS       AGU,

SUM(decode(TO_CHAR(a.telfeedate,               'mm'),       '09',     a.factration))         AS       SEP,

SUM(decode(TO_CHAR(a.telfeedate,               'mm'),       '10',     a.factration))         AS       OCT,

SUM(decode(TO_CHAR(a.telfeedate,               'mm'),       '11',     a.factration))         AS       NOV,

SUM(decode(TO_CHAR(a.telfeedate,               'mm'),       '12',     a.factration))          AS      DEC

FROM    (SELECT        a.userper,     a.tel,       a.standfee,      b.telfeedate,       b.factration

FROM                   TELFEESTAND                 a,               TELFEE                b

WHERE                     a.tel            =                    b.telfax)                a

GROUP      BY       a.userper,    a.tel,   a.standfee,          TO_CHAR(a.telfeedate,          'yyyy')

说          明           :          四        表            联       查        问       题                :

SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c
inner       join       d       on        a.a=d.d       where       .....

说      明        :     得     到     表    中       最     小      的     未     使    用      的        ID       号

SQL:

SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN
MIN(HandleID)     +     1      ELSE    1     END)     as      HandleID

FROM                                                 Handle

WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)

*******************************************************************************
有两个表 A 和 B,均有 key 和 value 两个字段,如果 B 的 key 在 A 中也有,就把 B 的 value
换          为          A        中          对          应         的          value
这道题的 SQL 语句怎么写?
update   b   set   b.value=(select    a.value   from   a   where   a.key=b.key)
where b.id     in(select    b.id from     b,a   where    b.key=a.key);
***************************************************************************
高级 sql 面试题
原                          表                          :
courseid                    coursename                   score
-------------------------------------
1                         java                        70
2                        oracle                        90
3                         xml                         40
4                         jsp                         30
5                        servlet                        80
-------------------------------------
为 了 便 于 阅 读 , 查 询 此 表 后 的 结 果 显 式 如 下 ( 及 格 分 数 为 60):
courseid              coursename             score               mark
---------------------------------------------------
1                 java                 70                   pass
2                 oracle                90                   pass
3                  xml                 40                   fail
4                  jsp                 30                   fail
5                servlet                 80                  pass
---------------------------------------------------
写出此查询语句
没     有     装     O      R     A     C    L      E      ,     没      试   过
select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as
mark from course
完                   全                  正                     确

SQL>                     desc                     course_v
Name                      Null?                      Type
----------------------------------------- -------- ----------------------------

COURSEID                                  NUMBER
COURSENAME                              VARCHAR2(10)
SCORE                                   NUMBER

SQL>           select           *            from            course_v;

COURSEID                   COURSENAME                     SCORE
----------                ----------                   ----------
1                        java                          70
2                       oracle                          90
3                        xml                           40
4                        jsp                           30
5                       servlet                         80
SQL>           select           courseid,           coursename           ,score
,decode(sign(score-60),-1,'fail','pass')    as    mark    from    course_v;

COURSEID              COURSENAME            SCORE              MARK
----------            ----------           ----------            ----
1                 java                 70                 pass
2                 oracle                90                 pass
3                  xml                 40                 fail
4                  jsp                 30                 fail
5 servlet 80 pass
*******************************************************************************
原                          表                          :

id                     proid                      proname
1                         1                         M
1                         2                         F
2                         1                         N
2                         2                         G
3                         1                         B
3                         2                         A
查            询            后            的            表            :

id                       pro1                       pro2
1                         M                          F
2                         N                          G
3                         B                          A
写出查询语句
解                  决                   方                    案

sql                   求                   解
表                                a
列                              a1              a2
记            录                         1          a
1                                b
2                                x
2                                y
2                                z
用     select   能    选   成      以     下   结     果    吗    ?
1                               ab
2                              xyz
使用 pl/sql 代码实现,但要求你组合后的长度不能超出 oracle varchar2 长度的限制。
下         面       是       一          个       例        子
create or replace type strings_table is table of varchar2(20);
/
create or replace function merge (pv in strings_table) return varchar2
is
ls                             varchar2(4000);
begin
for          i           in            1..pv.count             loop
ls            :=            ls             ||               pv(i);
end                                 loop;
return                                 ls;
end;
/
create     table       t     (id       number,name        varchar2(10));
insert           into            t              values(1,'Joan');
insert           into            t              values(1,'Jack');
insert            into            t              values(1,'Tom');
insert           into            t              values(2,'Rose');
insert           into            t             values(2,'Jenny');

column              names              format             a80;
select t0.id,merge(cast(multiset(select name from t where t.id = t0.id) as
strings_table))                            names
from       (select      distinct       id      from      t)      t0;

drop                    type                   strings_table;
drop                     function                     merge;
drop                        table                       t;




用                          sql                        :

Well if you have a thoretical maximum, which I would assume you would given the
legibility of listing hundreds of employees in the way you describe then yes.
But the SQL needs to use the LAG function for each employee, hence a hundred
emps      a      hundred      LAGs,      so      kind      of      bulky.

This example uses a max of 6, and would need more cut n pasting to do more than
that.

SQL>           select            deptno,           dname,         emps
2                          from                         (
3      select      d.deptno,     d.dname,     rtrim(e.ename     ||',     '||
4        lead(e.ename,1)       over       (partition      by       d.deptno
5          order          by           e.ename)           ||',            '||
6       lead(e.ename,2)        over        (partition        by       d.deptno
7          order          by           e.ename)           ||',            '||
8       lead(e.ename,3)        over        (partition        by       d.deptno
9          order          by           e.ename)           ||',            '||
10       lead(e.ename,4)        over       (partition         by       d.deptno
11          order          by           e.ename)           ||',            '||
12       lead(e.ename,5)        over       (partition         by       d.deptno
13         order          by         e.ename),',            ')          emps,
14      row_number       ()       over        (partition       by      d.deptno
15             order              by              e.ename)               x
16           from            emp            e,           dept               d
17            where            d.deptno              =            e.deptno
18                                          )
19               where               x                 =              1
20                                          /

DEPTNO                     DNAME                      EMPS
-------       -----------     ------------------------------------------
10           ACCOUNTING         CLARK,          KING,           MILLER
20     RESEARCH    ADAMS,   FORD,     JONES,    ROONEY,     SCOTT,     SMITH
30     SALES     ALLEN,   BLAKE,     JAMES,    MARTIN,     TURNER,      WARD

also
先                create              function                 get_a2;
create      or      replace     function      get_a2(       tmp_a1    number)
return                                   varchar2
is
Col_a2                                varchar2(4000);
begin
Col_a2:='';
for    cur     in     (select    a2     from    unite_a     where     a1=tmp_a1)
loop
Col_a2=Col_a2||cur.a2;
end                                      loop;
return                                   Col_a2;
end                                     get_a2;

select       distinct       a1       ,get_a2(a1)      from       unite_a
1                                      ABC
2                                      EFG
3 KMN
*******************************************************************************
一个 SQL 面试题
去年应聘一个职位未果,其间被考了一个看似简单的题,但我没有找到好的大案.
不知各位大虾有无好的解法?



题为:
有两个表, t1, t2,
Table t1:

SELLER | NON_SELLER
----- -----

A   B
A   C
A   D
B   A
B   C
B   D
C   A
C   B
C   D
D   A
D   B
D   C



Table t2:

SELLER | COUPON | BAL
----- --------- ---------
A 9 100
B 9 200
C 9 300
D 9 400
A 9.5 100
B 9.5 20
A 10 80




要求用 SELECT 语句列出如下结果:------如 A 的 SUM(BAL)为 B,C,D 的和,B 的 SUM(BAL)为
A,C,D 的和.......
且用的方法不要增加数据库负担,如用临时表等.

NON-SELLER| COUPON | SUM(BAL) ------- --------
A   9 900
B   9 800
C   9 700
D   9 600
A   9.5 20
B   9.5 100
C   9.5 120
D   9.5 120
A   10 0
B   10 80
C   10 80
D   10 80

关于论坛上那个 SQL 微软面试题
问                                           题                                           :

一百个账户各有 100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后 ,
请  输  出    每   天  所 有  账  户  的  余  额  信  息



这个问题的难点在于每个用户在某天可能有多条纪录,也可能一条纪录也没有(不包括第
一                  天                  )

返     回   的    记   录   集    是     一   个   100    天       *100   个   用   户   的   纪   录   集

下             面         是             我              的              思       路           :

1. 创 建 表 并 插 入 测 试 数 据 : 我 们 要 求 username 从 1-100
CREATE              TABLE                  [dbo].[TABLE2]               (
[username] [varchar]     (50)      NOT    NULL     ,    --   用    户    名
[outdate]   [datetime]        NOT      NULL       ,       --    日      期
[cash]     [float]          NOT         NULL         --       余        额
)                               ON                               [PRIMARY

declare                                         @i                                int
set                                                                              @i=1
while                                                                         @i<=100
                                                                                begin
              insert    table2        values(convert(varchar(50),@i),'2001-10-1',100)
              insert     table2        values(convert(varchar(50),@i),'2001-11-1',50)
                                                     set                      @i=@i+1
                                                                                  end
insert             table2              values(convert(varchar(50),@i),'2001-10-1',90)
select    *    from    table2    order     by    outdate,convert(int,username)

2.         组          合           查         询          语         句          :
a. 我 们 必 须 返 回 一 个 从 第 一 天 开 始 到 100 天 的 纪 录 集 :
如 : 2001-10-1 ( 这 个 日 期 是 任 意 的 )                              到      2002-1-8
由 于 第 一 天 是 任 意 一 天 , 所 以 我 们 需 要 下 面 的 SQL 语 句 :
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from                                                                    table2
group                                by                               username
order                          by                        convert(int,username)
这          里          的           奥         妙          在         于          :
convert(int,username)-1 ( 记 得 我 们 指 定 用 户 名 从 1-100 :-))
group by username,min(outdate): 第 一 天 就 可 能 每 个 用 户 有 多 个 纪 录 。
返              回               的              结              果              :
outdate
------------------------------------------------------
2001-10-01                                                        00:00:00.000
.........
2002-01-08                                                        00:00:00.000

b.   返     回     一    个     所    有     用    户     名     的   纪   录    集      :
select         distinct          username          from       table2
返                  回                   结                  果                 :
username
--------------------------------------------------
1
10
100
......
99

c. 返 回 一 个 100 天 记 录 集 和 100 个 用 户 记 录 集 的 笛 卡 尔 集 合 :
select                                *                                from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from                                                                 table2
group                              by                              username
order by convert(int,username)
)                                    as                                   A
CROSS                                 join
(
select         distinct        username        from         table2
)                                    as                                   B
order                        by                   outdate,convert(int,username)
返        回        结          果      100*100       条        纪        录        :
outdate                                                                username
2001-10-01       00:00:00.000                                                 1
......
2002-01-08       00:00:00.000                                                 100

d. 返     回    当 前 所 有 用 户 在                数 据     库 的       有    的 纪 录 :
select       outdate,username,min(cash)     as      cash         from      table2
group                             by                             outdate,username

order                        by                   outdate,convert(int,username)
返                  回                  纪                   录                  :
outdate                                                    username        cash
2001-10-01    00:00:00.000                           1                       90
......
2002-01-08    00:00:00.000                             100                    50

e. 将 c 中 返 回 的 笛 卡 尔 集 和 d 中 返 回 的 纪 录 做 left join:
select                                                     C.outdate,C.username,
D.cash
from
(
select                                  *                                   from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from                                                                      table2
group                                by                                 username
order                         by                           convert(int,username)
)                                      as                                      A
CROSS                                   join
(
select         distinct          username          from          table2
)                                      as                                      B
)                                      as                                      C
left                                                                        join
(
select      outdate,username,min(cash)       as       cash      from      table2
group                            by                             outdate,username
)                                      as                                      D
on(C.username=D.username         and          datediff(d,C.outdate,D.outdate)=0)

order       by             C.outdate,convert(int,C.username)
注意:用户在当天如果没有纪录,cash 字段返回 NULL,否则 cash 返回每个用户当天的余
额
outdate                                                       username    cash
2001-10-01    00:00:00.000                          1                       90
2001-10-01    00:00:00.000                         2                       100
......
2001-10-02 00:00:00.000           1         90
2001-10-02 00:00:00.000                 2                 NULL    <-- 注 意 这 里
......

2002-01-08    00:00:00.000                              100                50

f.好了,现在我们最后要做的就是,如果 cash 为 NULL,我们要返回小于当前纪录日期的
第一个用户余额(由于我们使用 order by cash,所以返回 top 1 纪录即可,使用 min 应该也
可     以  )  ,  这    个    余    额      即   为    当     前   的     余    额    :
case                                                      isnull(D.cash,0)
when                  0                        then
(
select  top  1 cash    from   table2    where   table2.username=C.username
and              datediff(d,C.outdate,table2.outdate)<0
order                          by                              table2.cash
)
else                                                                D.cash
end                               as                                  cash

g.     最     后    组      合      的        完     整      语      句      就      是
select                                                  C.outdate,C.username,
case                                                         isnull(D.cash,0)
when                    0                        then
(
select   top  1  cash    from   table2     where  table2.username=C.username
and                datediff(d,C.outdate,table2.outdate)<0
order                            by                               table2.cash
)
else                                                                   D.cash
end                                 as                                   cash
from
(
select                                 *                                 from
(
select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate
from                                                                   table2
group                             by                                 username
order                       by                          convert(int,username)
)                                   as                                      A
CROSS                                   join
(
select         distinct          username          from          table2
)                                      as                                      B
)                                      as                                      C
left                                                                        join
(
select      outdate,username,min(cash)       as       cash      from      table2
group                            by                             outdate,username
)                                      as                                      D
on(C.username=D.username         and          datediff(d,C.outdate,D.outdate)=0)

order                   by                    C.outdate,convert(int,C.username)

返                  回                   结                   果                 :
outdate                                           username                 cash
2001-10-01    00:00:00.000       1                                           90
2001-10-01    00:00:00.000       2                                          100
......
2002-01-08 00:00:00.000    100                50
*******************************************************************************
****
取出 sql 表中第 31 到 40 的记录(以自动增长 ID 为主键)
* 从 数 据 表 中 取 出 第 n 条 到 第 m 条 的 记 录 */

declare                      @m                     int
declare                      @n                     int
declare                  @sql                  varchar(800)
set                                  @m=40
set                                  @n=31
set @sql='select top '+str(@m-@n+1) + '* from idetail where autoid not in(
select     top    '+    str(@n-1)     +    'autoid     from   idetail)'
exec(@sql)



select top 10 * from t where id not in (select top 30 id from t order by id )
orde by id
-------------------------------------------------------------------------------
-
select top 10 * from t where id in (select top 40 id from t order by id) order
by id desc

*******************************************************************************
一       道        面       试        题       ,       写        sql       语       句
有 表 a 存 储 二 叉 树 的 节 点 , 要 用 一 条 sql 语 句 查 出 所 有 节 点 及 节 点 所 在 的 层 .
表                                 a
c1             c2             A             ----------1
----                   ----                    /                   
A              B              B              C             --------2
A                C               /                /                
B           D            D           N           E           ------3
C                E               /                                
D            F             F           K            I           ---4
E                                                                  I
D                                                                  K
C                                                                  N



所       要        得        到       的        结        果       如          下

jd                                                                     cs
-----                                                                ----
A                                                                       1
B                                                                       2
C                                                                       2
D                                                                       3
N                                                                       3
E                                                                       3
F                                                                       4
K                                                                       4
I                                                                       4
有高手指导一下,我只能用 pl/sql 写出来,请教用一条 sql 语句的写法
SQL>     select           c2,       level        +          1          lv
2                  from                    test                     start
3             with               c1                =                  'A'
4     connect           by       c1           =         prior          c2
5                                                                   union
6       select              'A',         1           from            dual
7                   order                     by                      lv;

C2                                                                      LV
--                                                              ----------
A                                                                        1
B                                                                        2
C                                                                        2
D                                                                        3
E                                                                        3
N                   3
F                   4
I                   4
K                   4

已   选   择   9   行   。

More Related Content

Viewers also liked

可视化与可视分析从数据拥有者到数据用户的桥梁
可视化与可视分析从数据拥有者到数据用户的桥梁可视化与可视分析从数据拥有者到数据用户的桥梁
可视化与可视分析从数据拥有者到数据用户的桥梁
gettyying
 
Oracle面市笔记
Oracle面市笔记Oracle面市笔记
Oracle面市笔记
yiditushe
 
下一代推荐引擎的关键技术及应用案例
下一代推荐引擎的关键技术及应用案例下一代推荐引擎的关键技术及应用案例
下一代推荐引擎的关键技术及应用案例
gettyying
 
数据挖掘竞赛经验分享 严强
数据挖掘竞赛经验分享 严强数据挖掘竞赛经验分享 严强
数据挖掘竞赛经验分享 严强
Felicia Wenyi Fei
 

Viewers also liked (17)

Sql培训 (1)
Sql培训 (1)Sql培训 (1)
Sql培训 (1)
 
可视化与可视分析从数据拥有者到数据用户的桥梁
可视化与可视分析从数据拥有者到数据用户的桥梁可视化与可视分析从数据拥有者到数据用户的桥梁
可视化与可视分析从数据拥有者到数据用户的桥梁
 
在线卡片分类测试和数据分析工具分享
在线卡片分类测试和数据分析工具分享在线卡片分类测试和数据分析工具分享
在线卡片分类测试和数据分析工具分享
 
不生病的理由
不生病的理由不生病的理由
不生病的理由
 
Oracle面市笔记
Oracle面市笔记Oracle面市笔记
Oracle面市笔记
 
下一代推荐引擎的关键技术及应用案例
下一代推荐引擎的关键技术及应用案例下一代推荐引擎的关键技术及应用案例
下一代推荐引擎的关键技术及应用案例
 
Banking Big Data Analytics
Banking Big Data AnalyticsBanking Big Data Analytics
Banking Big Data Analytics
 
Oracle数据库分析函数详解
Oracle数据库分析函数详解Oracle数据库分析函数详解
Oracle数据库分析函数详解
 
The simplethebeautiful
The simplethebeautifulThe simplethebeautiful
The simplethebeautiful
 
The Joys of Clean Data with Matt Dowle
The Joys of Clean Data with Matt DowleThe Joys of Clean Data with Matt Dowle
The Joys of Clean Data with Matt Dowle
 
面试常见问题
面试常见问题面试常见问题
面试常见问题
 
数据挖掘竞赛经验分享 严强
数据挖掘竞赛经验分享 严强数据挖掘竞赛经验分享 严强
数据挖掘竞赛经验分享 严强
 
网站分析及数据推动设计决策分享- Smartdesign Shanghai Taylor
网站分析及数据推动设计决策分享- Smartdesign Shanghai Taylor网站分析及数据推动设计决策分享- Smartdesign Shanghai Taylor
网站分析及数据推动设计决策分享- Smartdesign Shanghai Taylor
 
Market Timing, Big Data, and Machine Learning by Xiao Qiao at QuantCon 2016
Market Timing, Big Data, and Machine Learning by Xiao Qiao at QuantCon 2016Market Timing, Big Data, and Machine Learning by Xiao Qiao at QuantCon 2016
Market Timing, Big Data, and Machine Learning by Xiao Qiao at QuantCon 2016
 
Big Data Alchemy: How can Banks Maximize the Value of their Customer Data?
Big Data Alchemy: How can Banks Maximize the Value of their Customer Data?Big Data Alchemy: How can Banks Maximize the Value of their Customer Data?
Big Data Alchemy: How can Banks Maximize the Value of their Customer Data?
 
Working With Big Data
Working With Big DataWorking With Big Data
Working With Big Data
 
Visual Design with Data
Visual Design with DataVisual Design with Data
Visual Design with Data
 

More from yiditushe

Spring入门纲要
Spring入门纲要Spring入门纲要
Spring入门纲要
yiditushe
 
J Bpm4 1中文用户手册
J Bpm4 1中文用户手册J Bpm4 1中文用户手册
J Bpm4 1中文用户手册
yiditushe
 
性能测试实践2
性能测试实践2性能测试实践2
性能测试实践2
yiditushe
 
性能测试实践1
性能测试实践1性能测试实践1
性能测试实践1
yiditushe
 
性能测试技术
性能测试技术性能测试技术
性能测试技术
yiditushe
 
Load runner测试技术
Load runner测试技术Load runner测试技术
Load runner测试技术
yiditushe
 
J2 ee性能测试
J2 ee性能测试J2 ee性能测试
J2 ee性能测试
yiditushe
 
面向对象的Js培训
面向对象的Js培训面向对象的Js培训
面向对象的Js培训
yiditushe
 
Flex3中文教程
Flex3中文教程Flex3中文教程
Flex3中文教程
yiditushe
 
开放源代码的全文检索Lucene
开放源代码的全文检索Lucene开放源代码的全文检索Lucene
开放源代码的全文检索Lucene
yiditushe
 
基于分词索引的全文检索技术介绍
基于分词索引的全文检索技术介绍基于分词索引的全文检索技术介绍
基于分词索引的全文检索技术介绍
yiditushe
 
Lucene In Action
Lucene In ActionLucene In Action
Lucene In Action
yiditushe
 
Lucene2 4学习笔记1
Lucene2 4学习笔记1Lucene2 4学习笔记1
Lucene2 4学习笔记1
yiditushe
 
Lucene2 4 Demo
Lucene2 4 DemoLucene2 4 Demo
Lucene2 4 Demo
yiditushe
 
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
yiditushe
 
Lucene 3[1] 0 原理与代码分析
Lucene 3[1] 0 原理与代码分析Lucene 3[1] 0 原理与代码分析
Lucene 3[1] 0 原理与代码分析
yiditushe
 
7 面向对象设计原则
7 面向对象设计原则7 面向对象设计原则
7 面向对象设计原则
yiditushe
 
10 团队开发
10  团队开发10  团队开发
10 团队开发
yiditushe
 
9 对象持久化与数据建模
9  对象持久化与数据建模9  对象持久化与数据建模
9 对象持久化与数据建模
yiditushe
 
8 Uml构架建模
8  Uml构架建模8  Uml构架建模
8 Uml构架建模
yiditushe
 

More from yiditushe (20)

Spring入门纲要
Spring入门纲要Spring入门纲要
Spring入门纲要
 
J Bpm4 1中文用户手册
J Bpm4 1中文用户手册J Bpm4 1中文用户手册
J Bpm4 1中文用户手册
 
性能测试实践2
性能测试实践2性能测试实践2
性能测试实践2
 
性能测试实践1
性能测试实践1性能测试实践1
性能测试实践1
 
性能测试技术
性能测试技术性能测试技术
性能测试技术
 
Load runner测试技术
Load runner测试技术Load runner测试技术
Load runner测试技术
 
J2 ee性能测试
J2 ee性能测试J2 ee性能测试
J2 ee性能测试
 
面向对象的Js培训
面向对象的Js培训面向对象的Js培训
面向对象的Js培训
 
Flex3中文教程
Flex3中文教程Flex3中文教程
Flex3中文教程
 
开放源代码的全文检索Lucene
开放源代码的全文检索Lucene开放源代码的全文检索Lucene
开放源代码的全文检索Lucene
 
基于分词索引的全文检索技术介绍
基于分词索引的全文检索技术介绍基于分词索引的全文检索技术介绍
基于分词索引的全文检索技术介绍
 
Lucene In Action
Lucene In ActionLucene In Action
Lucene In Action
 
Lucene2 4学习笔记1
Lucene2 4学习笔记1Lucene2 4学习笔记1
Lucene2 4学习笔记1
 
Lucene2 4 Demo
Lucene2 4 DemoLucene2 4 Demo
Lucene2 4 Demo
 
Lucene 全文检索实践
Lucene 全文检索实践Lucene 全文检索实践
Lucene 全文检索实践
 
Lucene 3[1] 0 原理与代码分析
Lucene 3[1] 0 原理与代码分析Lucene 3[1] 0 原理与代码分析
Lucene 3[1] 0 原理与代码分析
 
7 面向对象设计原则
7 面向对象设计原则7 面向对象设计原则
7 面向对象设计原则
 
10 团队开发
10  团队开发10  团队开发
10 团队开发
 
9 对象持久化与数据建模
9  对象持久化与数据建模9  对象持久化与数据建模
9 对象持久化与数据建模
 
8 Uml构架建模
8  Uml构架建模8  Uml构架建模
8 Uml构架建模
 

Sql常见面试题

  • 1. Sql 常见面试题(总结) 1.用一条 SQL 语句 查询出每门课都大于 80 分的学生姓名 name kecheng fenshu 张 三 语 文 81 张 三 数 学 75 李 四 语 文 76 李 四 数 学 90 王 五 语 文 81 王 五 数 学 100 王 五 英 语 90 A: select distinct name from table where name not in (select distinct name from table where fenshu<=80) 2. 学 生 表 如 下 : 自 动 编 号 学 号 姓 名 课 程 编 号 课 程 名 称 分 数 1 2005001 张 三 0001 数 学 69 2 2005002 李 四 0001 数 学 89 3 2005001 张 三 0001 数 学 69 删 除 除 了 自 动 编 号 不 同 , 其 他 都 相 同 的 学 生 冗 余 信 息 A: delete tablename where 自动编号 not in(select min(自动编号) from tablename group by 学号,姓名,课程编号,课程名称,分数) 一个叫 department 的表,里面只有一个字段 name,一共有 4 条纪录,分别是 a,b,c,d,对应 四 个 球 对 , 现 在 四 个 球 对 进 行 比 赛 , 用 一 条 sql 语 句 显 示 所 有 可 能 的 比 赛 组 合 . 你先按你自己的想法做一下,看结果有我的这个简单吗? 答 : select a.name, b.name from team a, team b where a.name < b.name
  • 2. 请用 SQL 语句实现:从 TestDB 数据表中查询出所有月份的发生额都比 101 科目相应月份的 发 生 额 高 的 科 目 。 请 注 意 : TestDB 中 有 很 多 科 目 , 都 有 1 - 12 月 份 的 发 生 额 。 AccID : 科 目 代 码 , Occmonth : 发 生 额 月 份 , DebitOccur : 发 生 额 。 数据库名:JcyAudit,数据集:Select * from TestDB 答 : select a.* from TestDB a ,(select Occmonth,max(DebitOccur) Debit101ccur from TestDB where AccID='101' group by Occmonth) b where a.Occmonth=b.Occmonth and a.DebitOccur>b.Debit101ccur ******************************************************************************* ***** 面 试 题 : 怎 么 把 这 样 一 个 表 儿 year month amount 1991 1 1.1 1991 2 1.2 1991 3 1.3 1991 4 1.4 1992 1 2.1 1992 2 2.2 1992 3 2.3 1992 4 2.4 查 成 这 样 一 个 结 果 year m1 m2 m3 m4 1991 1.1 1.2 1.3 1.4 1992 2.1 2.2 2.3 2.4 答 案 一 、 select year, (select amount from aaa m where month=1 and m.year=aaa.year) as m1, (select amount from aaa m where month=2 and m.year=aaa.year) as m2, (select amount from aaa m where month=3 and m.year=aaa.year) as m3, (select amount from aaa m where month=4 and m.year=aaa.year) as m4 from aaa group by year 这 个 是 ORACLE 中 做 的 : select * from (select name, year b1, lead(year) over (partition by name order by year) b2, lead(m,2) over(partition by name order by year) b3,rank()over( partition by name order by year) rk from t) where rk=1; ******************************************************************************* ***** 精 妙 的 SQL 语 句 ! 精 妙 SQL 语 句
  • 3. 者 : 不 详 发 文 时 间 : 2003.05.29 10:55:05 说 明 : 复 制 表 ( 只 复 制 结 构 , 源 表 名 : a 新 表 名 : b) SQL: select * into b from a where 1<>1 说 明 : 拷 贝 表 ( 拷 贝 数 据 , 源 表 名 : a 目 标 表 名 : b) SQL: insert into b(a, b, c) select d,e,f from b; 说 明 : 显 示 文 章 、 提 交 人 和 最 后 回 复 时 间 SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b 说 明 : 外 连 接 查 询 ( 表 名 1 : a 表 名 2 : b) SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c 说 明 : 日 程 安 排 提 前 五 分 钟 提 醒 SQL: select * from 日 程 安 排 where datediff('minute',f 开 始 时 间 ,getdate())>5 说 明 : 两 张 关 联 表 , 删 除 主 表 中 已 经 在 副 表 中 没 有 的 信 息 SQL: delete from info where not exists ( select * from infobz where info.infid=infobz.infid ) 说 明 : -- SQL: SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE FROM TABLE1, (SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND FROM TABLE2
  • 4. WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, (SELECT NUM, UPD_DATE, STOCK_ONHAND FROM TABLE2 WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') ¦¦ '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y, WHERE X.NUM = Y.NUM ( + ) AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B WHERE A.NUM = B.NUM 说 明 : -- SQL: select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系 名 称 ='"&strdepartmentname&"' and 专 业 名 称 ='"&strprofessionname&"' order by 性 别 , 生 源 地 , 高 考 总 成 绩 说 明 : 从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源) SQL: SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY,
  • 5. SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV, SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration FROM TELFEESTAND a, TELFEE b WHERE a.tel = b.telfax) a GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') 说 明 : 四 表 联 查 问 题 : SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... 说 明 : 得 到 表 中 最 小 的 未 使 用 的 ID 号 SQL: SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID FROM Handle WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a) ******************************************************************************* 有两个表 A 和 B,均有 key 和 value 两个字段,如果 B 的 key 在 A 中也有,就把 B 的 value 换 为 A 中 对 应 的 value 这道题的 SQL 语句怎么写? update b set b.value=(select a.value from a where a.key=b.key)
  • 6. where b.id in(select b.id from b,a where b.key=a.key); *************************************************************************** 高级 sql 面试题 原 表 : courseid coursename score ------------------------------------- 1 java 70 2 oracle 90 3 xml 40 4 jsp 30 5 servlet 80 ------------------------------------- 为 了 便 于 阅 读 , 查 询 此 表 后 的 结 果 显 式 如 下 ( 及 格 分 数 为 60): courseid coursename score mark --------------------------------------------------- 1 java 70 pass 2 oracle 90 pass 3 xml 40 fail 4 jsp 30 fail 5 servlet 80 pass --------------------------------------------------- 写出此查询语句 没 有 装 O R A C L E , 没 试 过 select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course 完 全 正 确 SQL> desc course_v Name Null? Type ----------------------------------------- -------- ---------------------------- COURSEID NUMBER COURSENAME VARCHAR2(10) SCORE NUMBER SQL> select * from course_v; COURSEID COURSENAME SCORE ---------- ---------- ---------- 1 java 70 2 oracle 90 3 xml 40 4 jsp 30 5 servlet 80
  • 7. SQL> select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course_v; COURSEID COURSENAME SCORE MARK ---------- ---------- ---------- ---- 1 java 70 pass 2 oracle 90 pass 3 xml 40 fail 4 jsp 30 fail 5 servlet 80 pass ******************************************************************************* 原 表 : id proid proname 1 1 M 1 2 F 2 1 N 2 2 G 3 1 B 3 2 A 查 询 后 的 表 : id pro1 pro2 1 M F 2 N G 3 B A 写出查询语句 解 决 方 案 sql 求 解 表 a 列 a1 a2 记 录 1 a 1 b 2 x 2 y 2 z 用 select 能 选 成 以 下 结 果 吗 ? 1 ab 2 xyz 使用 pl/sql 代码实现,但要求你组合后的长度不能超出 oracle varchar2 长度的限制。 下 面 是 一 个 例 子 create or replace type strings_table is table of varchar2(20);
  • 8. / create or replace function merge (pv in strings_table) return varchar2 is ls varchar2(4000); begin for i in 1..pv.count loop ls := ls || pv(i); end loop; return ls; end; / create table t (id number,name varchar2(10)); insert into t values(1,'Joan'); insert into t values(1,'Jack'); insert into t values(1,'Tom'); insert into t values(2,'Rose'); insert into t values(2,'Jenny'); column names format a80; select t0.id,merge(cast(multiset(select name from t where t.id = t0.id) as strings_table)) names from (select distinct id from t) t0; drop type strings_table; drop function merge; drop table t; 用 sql : Well if you have a thoretical maximum, which I would assume you would given the legibility of listing hundreds of employees in the way you describe then yes. But the SQL needs to use the LAG function for each employee, hence a hundred emps a hundred LAGs, so kind of bulky. This example uses a max of 6, and would need more cut n pasting to do more than that. SQL> select deptno, dname, emps 2 from ( 3 select d.deptno, d.dname, rtrim(e.ename ||', '|| 4 lead(e.ename,1) over (partition by d.deptno
  • 9. 5 order by e.ename) ||', '|| 6 lead(e.ename,2) over (partition by d.deptno 7 order by e.ename) ||', '|| 8 lead(e.ename,3) over (partition by d.deptno 9 order by e.ename) ||', '|| 10 lead(e.ename,4) over (partition by d.deptno 11 order by e.ename) ||', '|| 12 lead(e.ename,5) over (partition by d.deptno 13 order by e.ename),', ') emps, 14 row_number () over (partition by d.deptno 15 order by e.ename) x 16 from emp e, dept d 17 where d.deptno = e.deptno 18 ) 19 where x = 1 20 / DEPTNO DNAME EMPS ------- ----------- ------------------------------------------ 10 ACCOUNTING CLARK, KING, MILLER 20 RESEARCH ADAMS, FORD, JONES, ROONEY, SCOTT, SMITH 30 SALES ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD also 先 create function get_a2; create or replace function get_a2( tmp_a1 number) return varchar2 is Col_a2 varchar2(4000); begin Col_a2:=''; for cur in (select a2 from unite_a where a1=tmp_a1) loop Col_a2=Col_a2||cur.a2; end loop; return Col_a2; end get_a2; select distinct a1 ,get_a2(a1) from unite_a 1 ABC 2 EFG 3 KMN ******************************************************************************* 一个 SQL 面试题
  • 10. 去年应聘一个职位未果,其间被考了一个看似简单的题,但我没有找到好的大案. 不知各位大虾有无好的解法? 题为: 有两个表, t1, t2, Table t1: SELLER | NON_SELLER ----- ----- A B A C A D B A B C B D C A C B C D D A D B D C Table t2: SELLER | COUPON | BAL ----- --------- --------- A 9 100 B 9 200 C 9 300 D 9 400 A 9.5 100 B 9.5 20 A 10 80 要求用 SELECT 语句列出如下结果:------如 A 的 SUM(BAL)为 B,C,D 的和,B 的 SUM(BAL)为 A,C,D 的和....... 且用的方法不要增加数据库负担,如用临时表等. NON-SELLER| COUPON | SUM(BAL) ------- --------
  • 11. A 9 900 B 9 800 C 9 700 D 9 600 A 9.5 20 B 9.5 100 C 9.5 120 D 9.5 120 A 10 0 B 10 80 C 10 80 D 10 80 关于论坛上那个 SQL 微软面试题 问 题 : 一百个账户各有 100$,某个账户某天如有支出则添加一条新记录,记录其余额。一百天后 , 请 输 出 每 天 所 有 账 户 的 余 额 信 息 这个问题的难点在于每个用户在某天可能有多条纪录,也可能一条纪录也没有(不包括第 一 天 ) 返 回 的 记 录 集 是 一 个 100 天 *100 个 用 户 的 纪 录 集 下 面 是 我 的 思 路 : 1. 创 建 表 并 插 入 测 试 数 据 : 我 们 要 求 username 从 1-100 CREATE TABLE [dbo].[TABLE2] ( [username] [varchar] (50) NOT NULL , -- 用 户 名 [outdate] [datetime] NOT NULL , -- 日 期 [cash] [float] NOT NULL -- 余 额 ) ON [PRIMARY declare @i int set @i=1 while @i<=100 begin insert table2 values(convert(varchar(50),@i),'2001-10-1',100) insert table2 values(convert(varchar(50),@i),'2001-11-1',50) set @i=@i+1 end insert table2 values(convert(varchar(50),@i),'2001-10-1',90)
  • 12. select * from table2 order by outdate,convert(int,username) 2. 组 合 查 询 语 句 : a. 我 们 必 须 返 回 一 个 从 第 一 天 开 始 到 100 天 的 纪 录 集 : 如 : 2001-10-1 ( 这 个 日 期 是 任 意 的 ) 到 2002-1-8 由 于 第 一 天 是 任 意 一 天 , 所 以 我 们 需 要 下 面 的 SQL 语 句 : select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate from table2 group by username order by convert(int,username) 这 里 的 奥 妙 在 于 : convert(int,username)-1 ( 记 得 我 们 指 定 用 户 名 从 1-100 :-)) group by username,min(outdate): 第 一 天 就 可 能 每 个 用 户 有 多 个 纪 录 。 返 回 的 结 果 : outdate ------------------------------------------------------ 2001-10-01 00:00:00.000 ......... 2002-01-08 00:00:00.000 b. 返 回 一 个 所 有 用 户 名 的 纪 录 集 : select distinct username from table2 返 回 结 果 : username -------------------------------------------------- 1 10 100 ...... 99 c. 返 回 一 个 100 天 记 录 集 和 100 个 用 户 记 录 集 的 笛 卡 尔 集 合 : select * from ( select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate from table2 group by username order by convert(int,username) ) as A CROSS join ( select distinct username from table2 ) as B
  • 13. order by outdate,convert(int,username) 返 回 结 果 100*100 条 纪 录 : outdate username 2001-10-01 00:00:00.000 1 ...... 2002-01-08 00:00:00.000 100 d. 返 回 当 前 所 有 用 户 在 数 据 库 的 有 的 纪 录 : select outdate,username,min(cash) as cash from table2 group by outdate,username order by outdate,convert(int,username) 返 回 纪 录 : outdate username cash 2001-10-01 00:00:00.000 1 90 ...... 2002-01-08 00:00:00.000 100 50 e. 将 c 中 返 回 的 笛 卡 尔 集 和 d 中 返 回 的 纪 录 做 left join: select C.outdate,C.username, D.cash from ( select * from ( select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate from table2 group by username order by convert(int,username) ) as A CROSS join ( select distinct username from table2 ) as B ) as C left join ( select outdate,username,min(cash) as cash from table2 group by outdate,username ) as D on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0) order by C.outdate,convert(int,C.username) 注意:用户在当天如果没有纪录,cash 字段返回 NULL,否则 cash 返回每个用户当天的余
  • 14. 额 outdate username cash 2001-10-01 00:00:00.000 1 90 2001-10-01 00:00:00.000 2 100 ...... 2001-10-02 00:00:00.000 1 90 2001-10-02 00:00:00.000 2 NULL <-- 注 意 这 里 ...... 2002-01-08 00:00:00.000 100 50 f.好了,现在我们最后要做的就是,如果 cash 为 NULL,我们要返回小于当前纪录日期的 第一个用户余额(由于我们使用 order by cash,所以返回 top 1 纪录即可,使用 min 应该也 可 以 ) , 这 个 余 额 即 为 当 前 的 余 额 : case isnull(D.cash,0) when 0 then ( select top 1 cash from table2 where table2.username=C.username and datediff(d,C.outdate,table2.outdate)<0 order by table2.cash ) else D.cash end as cash g. 最 后 组 合 的 完 整 语 句 就 是 select C.outdate,C.username, case isnull(D.cash,0) when 0 then ( select top 1 cash from table2 where table2.username=C.username and datediff(d,C.outdate,table2.outdate)<0 order by table2.cash ) else D.cash end as cash from ( select * from ( select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate from table2 group by username order by convert(int,username) ) as A
  • 15. CROSS join ( select distinct username from table2 ) as B ) as C left join ( select outdate,username,min(cash) as cash from table2 group by outdate,username ) as D on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0) order by C.outdate,convert(int,C.username) 返 回 结 果 : outdate username cash 2001-10-01 00:00:00.000 1 90 2001-10-01 00:00:00.000 2 100 ...... 2002-01-08 00:00:00.000 100 50 ******************************************************************************* **** 取出 sql 表中第 31 到 40 的记录(以自动增长 ID 为主键) * 从 数 据 表 中 取 出 第 n 条 到 第 m 条 的 记 录 */ declare @m int declare @n int declare @sql varchar(800) set @m=40 set @n=31 set @sql='select top '+str(@m-@n+1) + '* from idetail where autoid not in( select top '+ str(@n-1) + 'autoid from idetail)' exec(@sql) select top 10 * from t where id not in (select top 30 id from t order by id ) orde by id ------------------------------------------------------------------------------- - select top 10 * from t where id in (select top 40 id from t order by id) order by id desc ******************************************************************************* 一 道 面 试 题 , 写 sql 语 句
  • 16. 有 表 a 存 储 二 叉 树 的 节 点 , 要 用 一 条 sql 语 句 查 出 所 有 节 点 及 节 点 所 在 的 层 . 表 a c1 c2 A ----------1 ---- ---- / A B B C --------2 A C / / B D D N E ------3 C E / D F F K I ---4 E I D K C N 所 要 得 到 的 结 果 如 下 jd cs ----- ---- A 1 B 2 C 2 D 3 N 3 E 3 F 4 K 4 I 4 有高手指导一下,我只能用 pl/sql 写出来,请教用一条 sql 语句的写法 SQL> select c2, level + 1 lv 2 from test start 3 with c1 = 'A' 4 connect by c1 = prior c2 5 union 6 select 'A', 1 from dual 7 order by lv; C2 LV -- ---------- A 1 B 2 C 2 D 3 E 3
  • 17. N 3 F 4 I 4 K 4 已 选 择 9 行 。