|

|
1#
发表于 2005-5-4 16:14
| 只看该作者
[转帖]蛙蛙推荐:整理了一些SQL数据库技巧,贴一下
. R2 u* W ?4 H蛙蛙推荐:整理了一些SQL数据库技巧,贴一下
% v0 _( ?+ F6 z# W* U5 W一.怎样删除一个表中某个字段重复的列呀,举个例子 1 a/ P' w) u4 W9 ^6 M* A, N* F: G
表[table1] 2 q5 q& w, v: D# ?/ p/ K
id name ) S7 D% X( I: q$ b: |7 H6 S
1 aa & B: Z* S% @7 x- K: n1 Y
2 bb ' i8 S; T& h* c) |1 g# F
3 cc ' {" Q) N% g2 ]' x% f
1 aa 9 T& Y4 q, w9 d! c. P
2 bb
0 A0 U: b5 [: n9 m8 e3 cc ( w2 R' J2 e- ^1 B
我想最后的表是这样的 ; g8 Y; |( G# A0 z9 A+ r, A
id name ; `+ j/ i8 D4 B. P" @& y; G6 q" J3 C8 |. [
1 aa 5 J" Z; a+ H9 w) A
2 bb
# m4 e/ j1 h% m, L: o+ t- g3 cc ( |* }( m! E# ?& }5 _ ~9 Z2 B
回答:
7 t8 ~ o; r& Y将记录存到临时表#t中,重复的记录只存一条,然后将临时表#t中的记录再存回原表中,注意“select distinct id,class,name”要包含你需要的所有字段,否则有些字段就被删掉了。
3 x$ R3 t w1 G在查询管理器里执行下面代码: 9 u! l; W7 U% F+ g1 e
-----------------------------
# f8 C! U. Y$ ?+ N& T5 cSELECT DISTINCT id,, name
. X( ]2 Y) ?) F0 o6 d8 KINTO #t
, P5 [+ V% ^6 M/ `& F ^9 l( k/ [FROM table1 DELETE table1 " V9 x) F# o6 d, I
INSERT $ v8 `- |9 w d& b
INTO table1
1 |* M7 p; ^! Q4 N- {+ u' ySELECT * 4 j8 u; q$ e) R% e( U# k2 q1 }
FROM #t 1 ~, {8 u9 v2 O. c' C
------------------------------
. `" C4 p- u/ W, t: X. R二.找出既会VB又会PHP的人 , U( k* k0 U( k1 v
表是这样的:
( p. h% F x5 {; B! f `ID 员工 技能
5 p' u7 U$ }) e# k1 1 VB 8 d6 z- \; E9 o9 C
2 1 PHP ' {- \) d+ `( @$ E
3 1 ASP
6 N& M* n% G7 D8 S w% e( j- X4 2 PHP
1 r: K4 U1 d4 O( a/ _5 3 ASP * [5 J# Q0 P) O- f' B
6 4 VB . P) m( Y: U- ~ B7 R) e
7 4 ASP
2 b5 X) e& G4 z- v' ]要从这张表中找出既会VB又会PHP的人,SQL该怎么写啊?
0 u& j1 k$ T4 O4 g/ E" f# K0 g回答: & ?. x d, b1 T5 f# a0 u
--------------------------------------------------------------------------------------------- " B( Y. J4 F( v1 }6 z0 P
SELECT 员工 FROM [Table] WHERE 员工 IN(SELECT 员工 FROM [Table] WHERE 技能=';VB'; ) AND 技能=' HP'; & [8 q9 F* l# z t5 }
---------------------------------------------------------------------------------------------- . ]+ B# W- e$ f- z( l7 ]* w
三.数据库合并问题
3 A8 R# {2 a4 jaccess里的两个表,想让两个表的内容合并 6 `7 h* i2 c5 c8 P! g
表[a]结构如下: , P& }! h1 Z0 W; c
[id] 编号 自动编号
/ e) k* Q$ Q; E1 E) f ~[name] 名称 文本 - ^9 {+ b4 c% i" X
[price] 价格 数字
. K9 T, |2 P) {5 \& I1 v2 p! `6 w[guige] 规格 文本 u- g7 W1 Q3 L3 Z! C( D- X
[changjia] 生产厂家 文本 : Y2 C" y/ F# P8 w0 l* d+ x
[baozhuang] 包装 文本 , P- t" k7 s8 \
[danwei] 单位 文本
# M2 H7 j1 K9 y# @8 Q& \$ h L共有900条记录,除了id和name字段,其他均可以为空
3 m+ M- w! [1 t5 c# A/ {, l/ L; v表结构如下:
3 v9 ?* Q. |+ k[id] 编号 自动编号
9 E/ w- z8 T1 v1 h[name] 名称 文本
$ @ E# W- @3 r[price] 价格 数字
- m B/ m+ y: N3 R, T" _1 i9 x; h4 Y[changjia] 生产厂家 文本
+ e* F9 w/ \- w( `, N[danwei] 单位 文本
. V8 X3 ^+ C3 s. s7 ][xingzhi] 性质 文本 9 g' J" g' c2 }# h: T
共有800条记录,除了id和name字段,比表[a]少几个字段,但还多一个[xingzhi]的字符安其它均可以为空 Z( _6 Q0 \; U4 w
现在想生成一个新表[c],结构如下,而且内容是两个表的内容之和,
$ @# e, E5 Z+ ^8 _[id] 编号 自动编号
/ H* T/ l( C2 }7 |[name] 名称 文本
; Z$ s+ A. t( z6 @; V( @[price] 价格 数字
' ?9 c! b2 o% t c[guige] 规格 文本
$ O, m+ E4 U/ @* @4 G* I5 C+ q[changjia] 生产厂家 文本 7 Q- {) `. ]+ l
[baozhuang] 包装 文本
# U% F0 L( y6 u[danwei] 单位 文本 8 u* Y) `6 r8 k/ S6 L, u
[xingzhi] 性质 文本 , K/ m/ {* L6 M% A2 {( O5 _
用sql语句也可以,手工操作也好,xml也好,别管怎么着吧,怎么实现呀,哥们要郁闷坏了,真要让我们再输入800条记录,我就挂了,
9 K) o* Q# i K回答:
$ \. K2 a, w( Y+ k3 p0 n1.这样
8 W8 a+ i( ]; Q2 R9 f----------------------------- 2 @& r3 |/ w9 ]7 j: q
insert into c(id,name,.....)
) q& v- A+ i, n* pselect id,name,..... w0 [: d3 w% v! l
from a % H4 A# V6 d% `" |
insert into c(id,name,.....) 8 P. z+ d: w" ^1 j* u
select max(id)+1,name,..... 4 j8 Z3 \/ [8 N Y0 Q7 X
from b
: _9 B. f% N( H/ l------------------------------
; K7 z3 M. k1 @( N1 p0 Y* j2.更正: ! b# U+ d# c# d4 Z
如果直接在查询分析器里执行: ' @; Q; Y" z3 Z
-------------------------------
5 k* N; [. `4 m1 w* h% _7 l! t( X1 h5 yinsert into c(name,.....) 6 [7 M$ x; h* \) Z" ^5 |
select name,..... ( s9 k5 h$ {$ a& Q
from a
% B" V, K4 P( w/ x5 pinsert into c(name,.....)
+ k' Y9 B: [$ A+ G/ T$ Iselect name,..... 3 j# d3 _5 G" A! B: `9 S+ K4 h
from b C! W; e5 [- c [+ G# o, K
--------------------------------
" p2 h& w. M$ |6 h9 G7 h3.用union方法 ; ?* q; x _0 Z* n; B6 K
---------------------------------
: w* W% l5 Q% Yinsert into [c] ([id] ,编号,自动编号) * T8 a9 O8 a$ z! H
select [id],编号,自动编号 from [a] 9 i- x9 D, L3 l+ |
union , g% Z2 f! S+ m8 {( d3 V F
select [id],编号,自动编号 from
' j# W( S4 J, d8 j----------------------------------- / W" E! C2 r% j% ^9 V9 G
4.asp的解决办法
3 K" f" s/ }4 ^7 b9 ?------------------------------------------------------------
9 o z; Z/ X" O# U) I' @0 ]<% ';循环检测a表
" N8 I+ F- `5 J* C/ CSet rs = Server.CreateObect("ADODB.RECORDSET")
0 J7 M" A1 ]1 m# Irs.open "select * from a order by id",conn,1,1 : D, X! m1 v$ B% }
Do while not rs.eof
% x* h& b* f& |2 r- }# E( {Call actAdd(rs("name")) ';调用像b表添加内容的函数! 9 V3 j! j1 R& C6 Y
rs.MoveNext
* r% j8 l6 ?5 T: Y" V! d1 TLoop
9 h+ r G) C) Y* h9 Z: Ars.Close
& Q+ D/ @3 d$ { F; HSet rs = Nothing
5 c( {$ _( s% J; f- V# VSub actAdd(txt)
5 c. f5 ~" K/ S# Y; C7 ?# T- aDim ts, sql
0 q* |# A- S$ t: Wsql = "insert into b(name) values(';"& txt &"';)" + c8 r! t4 y% d2 z
Set ts = Conn.Execute(sql) : G% t4 U9 i( N) V1 B
ts.Close ' @0 ]4 L& v2 \- C) N3 u' d: u
Set ts = Nothing 6 R+ \0 U9 z" r1 N( ~! V) X
end Sub " A* s( e0 K/ n. s0 L% _! D) M
%>
. E0 N; ]# H3 o' I# j% W------------------------------------------------------------------ u1 k' v/ D: h4 u3 j
5.asp的解决办法
! S) G1 W! O% d6 u-----------------------------------------------------------------------------------
& s3 ^4 {1 X: K<% 1 v% S3 Q( L( b
dim arr_temp1,arr_temp2,arr_data $ S- w7 d* C5 m3 W2 l8 x
set rs=conn.execute("select id,name,price,guige,changjia,baozhuang,danwei from a")
/ z/ n) U2 l. c6 garr_temp1=rs.getrows
' ]" Q9 g7 r6 G" t( W! x' ^: qrs.close 7 s2 y5 B% n( D+ i9 j3 b4 j R
set rs=nothing
9 R+ ^% [$ Y O4 ^0 T$ A( _1 N! L6 jset rs=conn.execute("select id,name,price,guige,changjia,danwei,xingzhi from b") % F+ w( f' o6 S" ^
arr_temp2=rs.getrows
. { F$ L( b9 Y- Srs.close . t& A) g* s- K0 h1 h0 p( o5 H i3 W
set rs=nothing e3 ]. b7 A, z2 `. x
rem 开始处理
! ]$ W: Y: C- k1 v0 Oredim arr_data(ubound(arr_temp1,2)+ubound(arr_temp2,2),7)
( F5 A0 D" t9 a( q4 I G+ Z0 Frem 把两个数组的内容复制进来
M- ?# M# J" h4 D这一部分自己写了做两个循环 ( T4 t @% L/ {5 l
然后再存进数据库 5 O& b* p0 n% p& B; ?! ~" H3 e
%> 6 `4 o3 G3 F- g
---------------------------------------------------------------------------------------
0 E" e7 N+ q: Z3 N最后转一些经典的SQL语句:
1 I H) o' w8 ]) Y7 P; ?3 l1.蛙蛙推荐:一些精妙的SQL语句
3 ^1 X4 I6 |( r: O2 M G----------------------------------------------------------------------------------------------------------------------- - \2 u* J0 k4 x% d4 w
说明:复制表(只复制结构,源表名:a 新表名:b) " B, I' r' ?! r- c0 Y; K
SQL: select * into b from a where 1<>1 4 }6 g F% f# r" Z* p5 a1 t
8 X$ [- z6 t1 r
说明:拷贝表(拷贝数据,源表名:a 目标表名:b)
1 a. E# ?5 O4 ]: }$ m# h0 \* qSQL: insert into b(a, b, c) select d,e,f from b; 3 P Y$ x# y1 k
9 w4 K) A' i, M' I2 C: z说明:显示文章、提交人和最后回复时间
0 i$ A x! c7 S; ~2 ?/ y" QSQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
, q5 c7 Z" Z3 V. n- S0 s
, `& W& v: t2 o1 j1 J1 O. x! Z" l说明:外连接查询(表名1:a 表名2:b)
/ r: [ d- T& d& v4 _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
R9 M+ k. L3 A7 v& k7 s/ K% I3 T9 @- s) @2 E, I3 s
说明:日程安排提前五分钟提醒
; L% h$ X4 V4 f8 }SQL: select * from 日程安排 where datediff(';minute';,f开始时间,getdate())>5 2 h! a9 G- U4 [+ Q6 I' T9 P2 o
. e3 b1 f0 B/ [
( q7 [% @& j! O- {3 |9 E4 r/ l1 v
说明:两张关联表,删除主表中已经在副表中没有的信息
! [( f: ~% p$ `8 K1 m4 S& n% {SQL:
9 _8 y! m" q+ D' A7 u# y% {delete from info where not exists ( select * from infobz where info.infid=infobz.infid )
& a. b0 Z X0 }* N7 R1 g) {
2 q9 a0 w( o% c说明:--
9 a: ]3 c0 A! M$ ^! S8 b2 k, RSQL: * I2 j! v1 N( v- w/ R* Q9 m
SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE , m/ M. m/ u5 c7 n' W: |7 m
FROM TABLE1,
; M1 R1 U0 N6 G" b(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE % r- Q- V) i+ f* R9 A
FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND
. o; p# `9 p& n" CFROM TABLE2 ) L0 L- T; X* f7 Y+ o
WHERE TO_CHAR(UPD_DATE,';YYYY/MM';) = TO_CHAR(SYSDATE, ';YYYY/MM';)) X, ' ]1 `( J' N8 ]8 N' l
(SELECT NUM, UPD_DATE, STOCK_ONHAND
! h2 B6 Y% H7 n' P9 X- H2 a$ p0 ?/ RFROM TABLE2
?. n$ H3 r8 Y6 S3 qWHERE TO_CHAR(UPD_DATE,';YYYY/MM';) =
7 P0 U% e$ ?, A/ N$ ]" }: m& n, oTO_CHAR(TO_DATE(TO_CHAR(SYSDATE, ';YYYY/MM';) ¦¦ ';/01';,';YYYY/MM/DD';) - 1, ';YYYY/MM';) ) Y,
9 I! |* x3 l0 r3 N* b o# m; BWHERE X.NUM = Y.NUM (+)
( ]2 b+ D* i8 Z0 M" u6 E1 lAND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B
- Y" b* d d8 _/ o. BWHERE A.NUM = B.NUM 0 {; f4 V3 [, |, {( Z8 o& A
/ p. [% c3 T2 c4 k$ j: A% ^$ S说明:--
2 H6 ] z$ @) i5 kSQL:
, L% t [1 W* j4 S' sselect * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称=';"&strdepartmentname&"'; and 专业名称=';"&strprofessionname&"'; order by 性别,生源地,高考总成绩
3 ^0 b' w4 i% v% P
1 g% |5 h) S `$ M/ v说明:
w' R! {: f. t8 H3 T" L从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源) 3 k |: f" ~8 b4 \* T# D0 B
SQL:
" S; T: W, g1 [7 l' H: `SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, ';yyyy';) AS telyear, ' O+ q6 s( y* ]; F3 Y0 Q
SUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';01';, a.factration)) AS JAN, ( D) j) `2 z( c( A% o2 ^2 i
SUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';02';, a.factration)) AS FRI,
% _2 `) B% M* h$ q. P! ~6 rSUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';03';, a.factration)) AS MAR,
& h' e- D) E& t& `SUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';04';, a.factration)) AS APR,
* A6 U$ l. ]) M4 c; K# u: x$ USUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';05';, a.factration)) AS MAY,
- c8 J/ j0 g+ @3 H/ b+ V* _5 y6 ZSUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';06';, a.factration)) AS JUE,
4 U6 R0 {; [3 |& Q2 L' NSUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';07';, a.factration)) AS JUL, 6 W1 c9 s3 B& _4 n
SUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';08';, a.factration)) AS AGU, " A" j& {4 t% [+ k/ \6 l
SUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';09';, a.factration)) AS SEP, 1 m& z. a+ V# N) a1 n
SUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';10';, a.factration)) AS OCT,
. ]( E( q4 j) v1 ^) v: g6 sSUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';11';, a.factration)) AS NOV,
/ D/ d% H7 J8 w& Q0 X5 ]SUM(decode(TO_CHAR(a.telfeedate, ';mm';), ';12';, a.factration)) AS DEC
4 C7 e7 \& ~) r2 j% @! KFROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration
; U i9 h5 ]. Q2 A9 \FROM TELFEESTAND a, TELFEE b + Q' q+ F6 x g8 f, x: d
WHERE a.tel = b.telfax) a
+ X: x# v% W- F+ G7 H7 C& `GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, ';yyyy';) 5 C% s) {1 |+ Q% k+ \" G. E
4 m& f9 ?4 d* T. }% T, B5 Q: g6 m说明:四表联查问题: ! ?; }: \& \' ~! J! K
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 .....
@3 ` c; c0 I Y' P; j& v" ~ B# E- v' k- c- M& K0 ?
说明:得到表中最小的未使用的ID号 / a6 h. H8 F* r, \* i* I6 i/ N$ Y( ]
SQL: : F- ^" S, k# y
SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID 4 ~5 s1 w; S5 e, u$ H
FROM Handle ! S @3 a9 c5 Q
WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a) + |0 J3 C5 h# Z5 z6 F
-----------------------------------------------------------------------------------------------------------------------
+ e/ a9 Y: M, s8 u4 a2.删除重复数据
) e( H! {) f/ j; h/ ~-----------------------------------------------------------------------------------------------------------------------
1 d: ^" E* n ~一、具有主键的情况 2 y! D, C' d0 Q) A% w
a.具有唯一性的字段id(为唯一主键)
: z$ [% Q& @ pdelete table # M) O" \, \4 X( s; E- P
where id not in
. z7 H0 {; x z' N% R( 4 F( b& X" L4 W( h" y C
select max(id) from table group by col1,col2,col3...
, G4 h( H+ i9 s8 ?) 3 k/ |" m2 ~! O+ u& F1 r
group by 子句后跟的字段就是你用来判断重复的条件,如只有col1,
, H7 j% W8 {' g3 T- n U那么只要col1字段内容相同即表示记录相同。
' H/ b7 z, v: h' v" [b.具有联合主键 & t+ `! c7 r: A& g# J3 |+ L R
假设col1+';,';+col2+';,';...col5 为联合主键
/ H% q r* ?5 F& T0 oselect * from table where col1+';,';+col2+';,';...col5 in ( ' F. D/ h V/ ~
select max(col1+';,';+col2+';,';...col5) from table
( ?, S3 H* D0 n0 y+ ewhere having count(*)>1
; K4 y, w r6 z/ ^group by col1,col2,col3,col4
# a) }# n9 w0 C5 B$ r) 4 @- Q; L& e! v, L+ Y
group by 子句后跟的字段就是你用来判断重复的条件, & e0 s4 g$ F- S
如只有col1,那么只要col1字段内容相同即表示记录相同。
+ p: d l# c5 t& i- a% v2 bc:判断所有的字段 ; Z) ]% t2 q$ D' i p% N
select * into #aa from table group by id1,id2,.... 7 x% R2 p w. V0 }
delete table
7 Z8 f" ?/ b! D7 {& cinsert into table
- \; X( }7 _) d4 Y2 wselect * from #aa
6 E9 n6 U0 q" s* ~二、没有主键的情况 % O8 P& `7 _5 d, m) {& I" m
a:用临时表实现 6 {2 a t1 n3 A8 g
select identity(int,1,1) as id,* into #temp from ta 9 b, C! T* i2 k& R) D: e {
delete #temp , l s2 _+ n/ c' F/ ]/ d
where id not in
1 V" a( ^& v$ s0 H$ A(
4 k R- {9 A+ x7 o( v- }3 eselect max(id) from # group by col1,col2,col3... / f* l& I; E: Y* H8 Q' S1 d
)
' h) `" l- y; X( O, J+ O! Fdelete table ta , L7 B; V, z% k/ [" S% o
inset into ta(...)
- q8 P2 B6 L- `1 y) j; ?5 U/ h! K: mselect ..... from #temp
2 L ]; K/ r. K) z6 j; ]b:用改变表结构(加一个唯一字段)来实现 , d% }0 s* j7 z$ ^
alter table 表 add newfield int identity(1,1) ) ?6 l" c8 u! L
delete 表 + q b( z9 ]5 a$ } }3 ]" k0 I
where newfield not in
7 Z, g% T6 L( @! ~/ j# r6 f; ^ O5 Z(
* a+ H9 C' o9 \" f, Tselect min(newfield) from 表 group by 除newfield外的所有字段
" @$ v0 X, s L2 q)
7 f8 X# z* p3 S6 S5 Aalter table 表 drop column newfield
& i7 a' A4 O; N$ U4 c2 O 3 c0 y3 v% a% b
- X# Q$ ]+ s3 `: |% P5 a2 P% Q8 s
转自:www.webasp.net |
|