常用sql

 

 

一、SQL. 3

1、数据定义语言(DDL). 3

2、数据操作语言(DML). 3

3、数据控制语言(DCL)... 3

二、DDL. 4

1、创建数据库... 4

2、删除数据库... 4

3、备份sql server. 4

4、创建表... 4

5、删除表... 4

6、基表修改... 4

6.1、增加一个字段... 4

6.2、修改字段类型... 4

6.3、将某个字段设为主键... 4

6.4、将某个字段的主键定义取消... 4

7、初始化表:(Access数据库目前不支持)... 4

8、创建视图:(Access数据库目前不支持)... 5

9、删除视图:DROP VIEW. 5

10、创建索引:... 5

11、删除索引:... 5

12、收缩数据库... 5

13、压缩数据库... 5

14、转移数据库给新用户以已存在用户权限... 5

15、检查备份集... 5

16、修复数据库... 5

17、日志清除... 6

18、更改某个表... 7

19、存储更改全部表... 7

20.通过SQL语句来更改用户的密码... 8

三、DML. 8

1INSERT. 8

1.1、简单插入... 8

1.2、将表1查询结果插入表2. 8

1.3 跨数据库之间表的拷贝... 8

2DELETE. 8

2.1、简单删除... 8

2.2、删除重复记录... 8

2.3、两张关联表,删除主表中已经在副表中没有的信息... 8

3UPDATE. 8

3.1、简单修改... 8

4SELECT. 8

4.1、简单查询,条件查询... 8

4.2、排序... 9

4.3、多表简单查询... 9

4.4、统计记录... 9

4.5、group. 9

4.6、Top. 9

4.7、SUM(),AVG(),MAX(),MIN(). 10

4.8、EXISTS. 10

4.9、IN,子查询... 10

4.10、LIKE. 10

4.11、BETWEEN. 10

4.12、连接类型... 10

4.13、内连接Inner Join(普通连接、自然连接)... 11

4.14、外连接... 11

4.15、自身连接... 13

4.16、交叉连接... 13

4.17、UNION 运算符... 13

4.18、EXCEPT 运算符... 13

4.19、INTERSECT 运算符... 13

4.20、随即读取数据... 14

4.21、INTO制表... 14

4.22、SQL Server日期计算... 14

4.23、得到表中最小的未使用的ID... 14

4.24、列出数据库里所有的表名... 14

4.25、显示文章、提交人和最后回复时间... 14

4.26、在线视图查询(表名1:a ). 15

4.27、四表联查问题:... 15

4.28、日程安排提前五分钟提醒  SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5. 15

4.29、一条sql 语句搞定数据库分页 select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段... 15

4.30、选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.). 15

4.31、包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表... 15

4.32、列出表里的所有的... 15

4.33、列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case  15

4.34、如何在数据库里找到含有相同字段的表?... 15

4.35、查询数据的最大排序问题(只能用一条语句写)... 16

4.36、怎么判断出一个表的哪些字段不允许为空?... 16

4.37、如何在数据库里找到含有相同字段的表?... 16

4.38、怎么判断出一个表的哪些字段不允许为空?... 17

4.39、查询第xxx行数据... 17

4.40、快速获取表test的记录总数[对大容量表非常有效]. 17

4.41、获取表结构[把 'sysobjects' 替换 成 'tablename' 即可]. 18

4.42、提取数据库内所有表的字段详细说明的SQL语句... 18

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

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

4.45、一个SQL语句的问题:行列转换... 20

4.46、求助!快速比较结构相同的两表 结构相同的两表,一表有记录3万条左右,一表有记录2万条左右,我怎样快速查找两表的不同记录? ============================ 给你一个测试方法,从northwind中的orders表取数据。 select * into n1 from orders select * into n2 from orders. 21

三、存储过程... 22

1. 1=1,1=2的使用,在SQL语句组合时用的较多... 22

2. SQL SERVER中直接循环写入数据... 22

3. 小记存储过程中经常用到的本周,本月,本年函数... 23

4.如何删除一个表中重复的记录?... 23

5. 行列转换--普通... 26

6. 行列转换--合并... 26

7. 如何取得一个数据表的所有列名... 27

8.. 27

9.. 27

10.. 27

 

一、SQL

SQL全称是结构化查询语言(Structured Query Language)”

  SQL(Structured Query Language)是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。

  SQL同时也是数据库脚本文件的扩展名。

SQL语言包含4个部分:

  ※ 数据定义语言(DDL),例如:CREATEDROPALTER等语句。

  ※ 数据操作语言(DML),例如:INSERTUPDATEDELETE语句。

  ※ 数据查询语言(DQL),例如:SELECT语句。

  ※ 数据控制语言(DCL),例如:GRANTREVOKECOMMITROLLBACK等语句。

SQL语言包括三种主要程序设计语言类别的陈述式:数据定义语言(DDL),数据操作语言(DML)及数据控制语言(DCL)

1、数据定义语言(DDL)

DDL 用于定义和管理物件,例如资料库、资料表以及检视表(第18章 将会解释何谓检视表)。DDL 陈述式通常包括每个物件的CREATEALTER 以及 DROP 命令。举例来说,CREATE TABLEALTER TABLE 以及 DROP TABLE 这些陈述式便可以用来建立新资料表、修改其属性(如新增或删除资料行)、删除资料表等。

2、数据操作语言(DML)

DML 利用 INSERTSELECTUPDATE DELETE 等陈述式来操作资料库物件所包含的资料。

3、数据控制语言(DCL)

DCL是用来管理数据库的语言。包含管理权限及数据更改。

SQL的数据控制功能包括存取控制和完整性控制,为了防止非法用户对数据的使用和破坏,提供了GRANTREVOKE语句,是对操作的授权控制语句。

二、DDL

1、创建数据库

CREATE DATABASE database_name

2、删除数据库

drop database database_name

3、备份sql server

--- 创建 备份数据的 device

USE master

EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'

--- 开始 备份

BACKUP DATABASE pubs TO testBack

4、创建表

CREATE TABLE table_name(

column1 DATATYPE [NOT NULL] [NOT NULL PRIMARY KEY],

column2 DATATYPE [NOT NULL],)

 

 

说明:上面的DATATYPE 指的是字段的类型,NUT NULL 指是否为空,PRIMARY KEY 指本表的主键。

例:定义表student

CREATE TABLE Student (

Id CHAR(6) NOT NULL,

Name CHAR(10) NOT NULL,

Age INTEGER NOT NULL,

Sex CHAR(8) NOT NULL

)

根据已有的表创建新表:

Acreate table tab_new like tab_old (使用旧表创建新表)

Bcreate table tab_new as select col1,col2… from tab_old definition only

5、删除表

公式:DROP TABLE 基表名

例子:DROP TABLE Student

6、基表修改

ALTER TABLE 表名 ADD(OR MODIFY) 域名 数据类型

6.1、增加一个字段

ALTER TABLE Student ADD Age CHAR(4)

说明:增加一个字段。在表Student上增加一个域名为性别(Age),其数据类型为CHAR4

注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。

ALTER TABLE table_name ADD COLUMN column_name DATATYPE

6.2、修改字段类型

ALTER TABLE Student MODIFY Sex CHAR(10)        Access数据库不支持MODIFY

说明:修改字段类型。将表Student上的Sex的字符串长度改为10

6.3、将某个字段设为主键

ALTER TABLE table_name ADD PRIMARY KEY (column_name)

6.4、将某个字段的主键定义取消

ALTER TABLE table_name DROP PRIMARY KEY (column_name)

7、初始化表:(Access数据库目前不支持)

公式:TRUNCATE TABLE 表名

例子:TRUNCATE TABLE table1

说明:初始化表table1(删除表中所有信息)

8、创建视图:(Access数据库目前不支持)

CREATE VIEW  视图名 [(域名表)] AS SELECT语句)

create view viewname as select statement

9、删除视图:DROP VIEW

DROP VIEW 视图名

10、创建索引:

CREATE [UNIQUE] INDEX 索引名 ON [(域名表)] AS SELECT语句)

//create [unique] index idxname on tabname(col….)

例:对关系StudentId域创建名为index_name的索引

CREATE UNIQUE INDEX index_name ON Student (Id)

用于对基表建立索引以提供对基表的存取路径。

说明:为数据表格的某个字段建立索引以增加查询时的速度

11、删除索引:

DROP INDEX 索引名 ON 基表名

//drop index idxname

例:DROP INDEX SNO ON Student

注:索引是不可更改的,想更改必须删除重新建。

 

12、收缩数据库

--重建索引

DBCC REINDEX

DBCC INDEXDEFRAG

--收缩数据和日志

DBCC SHRINKDB

DBCC SHRINKFILE

13、压缩数据库

dbcc shrinkdatabase(dbname)

14、转移数据库给新用户以已存在用户权限

exec sp_change_users_login 'update_one','newname','oldname'

go

15、检查备份集

RESTORE VERIFYONLY from disk='E:\dvbbs.bak'

16、修复数据库

ALTER DATABASE [dvbbs] SET SINGLE_USER

GO

DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK
GO

ALTER DATABASE [dvbbs] SET MULTI_USER
GO

 

17、日志清除

SET NOCOUNT ON
DECLARE @LogicalFileName sysname,
        @MaxMinutes INT,
        @NewSize INT


USE     tablename             --
要操作的数据库名
SELECT  @LogicalFileName = 'tablename_log',  --
日志文件名
@MaxMinutes = 10,               -- Limit on time allowed to wrap log.
        @NewSize = 1                  --
你想设定的日志文件的大小(M)

-- Setup / initialize
DECLARE @OriginalSize int
SELECT @OriginalSize = size
  FROM sysfiles
  WHERE name = @LogicalFileName
SELECT 'Original Size of ' + db_name() + ' LOG is ' +
        CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' +
        CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB'
  FROM sysfiles
  WHERE name = @LogicalFileName
CREATE TABLE DummyTrans
  (DummyColumn char (8000) not null)


DECLARE @Counter   INT,
        @StartTime DATETIME,
        @TruncLog  VARCHAR(255)
SELECT  @StartTime = GETDATE(),
        @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY'

DBCC SHRINKFILE (@LogicalFileName, @NewSize)
EXEC (@TruncLog)
-- Wrap the log if necessary.
WHILE     @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired
      AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName) 
      AND (@OriginalSize * 8 /1024) > @NewSize 
  BEGIN -- Outer loop.
    SELECT @Counter = 0
    WHILE  ((@Counter < @OriginalSize / 16) AND (@Counter < 50000))
      BEGIN -- update
        INSERT DummyTrans VALUES ('Fill Log') 
        DELETE DummyTrans
        SELECT @Counter = @Counter + 1
      END  
    EXEC (@TruncLog) 
  END  
SELECT 'Final Size of ' + db_name() + ' LOG is ' +
        CONVERT(VARCHAR(30),size) + ' 8K pages or ' +
        CONVERT(VARCHAR(30),(size*8/1024)) + 'MB'
  FROM sysfiles
  WHERE name = @LogicalFileName
DROP TABLE DummyTrans
SET NOCOUNT OFF

18、更改某个表

exec sp_changeobjectowner 'tablename','dbo'

19、存储更改全部表

CREATE PROCEDURE dbo.User_ChangeObjectOwnerBatch
 @OldOwner as NVARCHAR(128),
 @NewOwner as NVARCHAR(128)
AS

DECLARE @Name   as NVARCHAR(128)
DECLARE @Owner  as NVARCHAR(128)
DECLARE @OwnerName  as NVARCHAR(128)

DECLARE curObject CURSOR FOR
 select 'Name'   = name,
  'Owner'   = user_name(uid)
 from sysobjects
 where user_name(uid)=@OldOwner
 order by name

OPEN  curObject
FETCH NEXT FROM curObject INTO @Name, @Owner
WHILE(@@FETCH_STATUS=0)
BEGIN    
 if @Owner=@OldOwner
 begin
  set @OwnerName = @OldOwner + '.' + rtrim(@Name)
  exec sp_changeobjectowner @OwnerName, @NewOwner
 end
-- select @name,@NewOwner,@OldOwner

 FETCH NEXT FROM curObject INTO @Name, @Owner
END

close curObject
deallocate curObject
GO

20.通过SQL语句来更改用户的密码

修改别人的,需要sysadmin role
EXEC sp_password NULL, 'newpassword', 'User'

如果帐号为SA执行EXEC sp_password NULL, 'newpassword', sa

 

 

 

 

三、DML

1INSERT

1.1、简单插入

INSERT INTO table_name(column1,column2,...) VALUES (value1,value2, ...)

说明:在插入语句中,若不指明要插入字段则,按表中的字段顺序依次插入。

另外,插入数据的类型应和所插入字段的类型相匹配。

1.2、将表1查询结果插入表2

INSERT INTO table_name (column1,column2,...) SELECT columnx,columny,...FROM another_table

说明:通过一个子查询将别的表格相应字段的值插入该表格。

说明:拷贝表(拷贝数据,源表名:table_name 目标表名:another_table) (Access可用)

1.3、 跨数据库之间表的拷贝

insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件

说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)

举例:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..

2DELETE

2.1、简单删除

DELETE FROM table_name WHERE conditions

说明:删除符合条件的记录。

2.2、删除重复记录

Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

2.3、两张关联表,删除主表中已经在副表中没有的信息

delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )

 

 

3UPDATE

3.1、简单修改

UPDATE table_name SET column1=’x’,column2=’y’ WHERE conditions

说明:该语句表示在某种条件下将column1字段的值改为x。若不加条件,则默认该字段全部更改。

4SELECT

4.1、简单查询,条件查询

SELECT column1,columns2,... FROM table_name

SELECT * FROM table_name WHERE column1 = x AND column2 > y

4.2、排序

SELECT column1,column2 FROM table_name ORDER BY column2 [DESC],column1

说明:ORDER BY 是指定以某个字段排序,[DESC]是指从大到小排列,若没有指明,则是从小到大排列。

4.3、多表简单查询

SELECT * FROM table1,table2 WHERE table1.colum1=table2.column1

说明:这是一个组合查询,查询两个表格中 column1字段具有相同值的记录。作为两个表中建立关系的字段,

其类型必须匹配。

4.4、统计记录

SELECT COUNT (*) FROM table_name WHERE column_name = x

说明:查询符合条件的记录数。

4.5group

常用于统计时,如分组查总数:

select gender,count(sno) from students group by gender

 (查看男女学生各有多少) 

注意:从哪种角度分组就从哪列"group by"

对于多重分组,只需将分组规则罗列。比如查询各届各专业的男女同学人数 ,那么分组规则有:届别(grade)、专业(mno)和性别(gender),所以有"group by grade, mno, gender"

select grade, mno, gender, count(*)

from students

group by grade, mno, gender

 

通常group还和having联用,比如查询1门课以上不及格的学生,则按学号(sno)分类有:

select sno,count(*) from grades

where mark<60

group by sno

having count(*)>1

 

4.6Top

select top 10 * form table1 where 范围

select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc

说明:选择从1015的记录

 

四种方法取表里nm条纪录

1.

select top m * into 临时表(或表变量) from tablename order by columnname

set rowcount n

select * from 表变量 order by columnname desc

 

2.select top n * from (select top m * from tablename order by columnname) a order by columnname desc

 

3.如果tablename里没有其他identity列,那么:

select identity(int) id0,* into #temp from tablename

nm条的语句为:

select * from #temp where id0 >=n and id0 <= m

如果你在执行select identity(int) id0,* into #temp from tablename这条语句的时候报错,那是因为你的DB中间的select into/bulkcopy属性没有打开要先执行:

exec sp_dboption 你的DB名字,'select into/bulkcopy',true

 

4.如果表里有identity属性,那么简单:

select * from tablename where identitycol between n and m

 

 

4.7SUM()AVG()MAX()MIN()

求和:select sum(field1) as sumvalue from table1

平均:select avg(field1) as avgvalue from table1

最大:select max(field1) as maxvalue from table1

最小:select min(field1) as minvalue from table1

4.8EXISTS

SELECT * FROM table_name1 WHERE EXISTS (SELECT * FROM table_name2 WHERE conditions)

说明:这条查询语句用一个子查询语句作为该查询语句的条件。EXISTS指是否存在。

4.9IN,子查询

select * from table1 where a [not] in (‘1’,’2’,’4’,’6’)

select a,b,c from table1 where a IN (1,2,3)

select a,b,c from table1 where a IN (select d from table2 )

SELECT * FROM table_name1 WHERE column1 IN (SELECT column1 FROM table_name2 WHERE conditions )

说明:IN后面接的是一个集合,表示将column1字段的值在集合中的所有记录从table_name1表中选出来。

4.10LIKE

SELECT * FROM table_name1 WHERE column1 LIKE ‘x%‘

说明:该语句为模糊查询。这里的“%”是一个通配符,表示将column1字段中以x开头的所有记录选出来。

4.11BETWEEN

SELECT * FROM table_name1 WHERE column1 BETWEEN x AND y

select * from table1 where time between time1 and time2

select a,b,c, from table1 where a not between 数值1 and 数值2

说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括

4.12、连接类型

在关系代数中,连接运算是由一个笛卡尔积运算和一个选取运算构成的。首先用笛卡尔积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,确保只把分别来自两个数据集合并且具有重叠部分的行合并在一起。连接的全部意义在于在水平方向上合并两个数据集合(通常是表),并产生一个新的结果集合,其方法是将一个数据源中的行于另一个数据源中和它匹配的行组合成一个新元组。

SQL提供了多种类型的连接方式,它们之间的区别在于:从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同。

连接类型        定义

内连接        只连接匹配的行

左外连接        包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行

右外连接        包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行

全外连接        包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。

(H)(theta)连接        使用等值以外的条件来匹配左、右两个表中的行

交叉连接        生成笛卡尔积-它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行都一一匹配

INFORMIX中连接表的查询

如果FROM子句指定了多于一个表引用,则查询会连接来自多个表的行。连接条件指定各列之间(每个表至少一列)进行连接的关系。因为正在比较连接条件中的列,所以它们必须具有一致的数据类型。

SELECT语句的FROM子句可以指定以下几种类型的连接

FROM子句关键字        相应的结果集

CROSS JOIN        笛卡尔乘积(所有可能的行对)

INNER JOIN        仅对满足连接条件的CROSS中的列

LEFT OUTER JOIN        一个表满足条件的行,和另一个表的所有行

RIGHT OUTER JOIN        LEFT相同,但两个表的角色互换

FULL OUTER JOIN        LEFT OUTER RIGHT OUTER中所有行的超集

4.13、内连接Inner Join(普通连接、自然连接)

只连接匹配的行。

select g.sno,s.name,c.coursename

from grades g JOIN students s ON g.sno=s.sno

JOIN courses c

ON g.cno=c.cno

 

select *

from  t_institution i inner join t_teller t

on i.inst_no = t.inst_no

where i.inst_no = "5801"

其中inner可以省略。

 

等价于早期的连接语法

select *

from t_institution i, t_teller t

where i.inst_no = t.inst_no and i.inst_no = "5801"

 

4.14、外连接

4.14.1、左外连接(Left Outer Jion)

包含左边表的全部行(不管右边的表中是否存在与它们匹配的行),以及右边表中全部匹配的行。

select *

from table_1 i left outer join table_2 t

on i.Id = t.Id

其中outer可以省略。

select courses.cno,max(coursename),count(sno)

from courses LEFT JOIN grades ON courses.cno=grades.cno

group by courses.cno
左连接特点:显示全部左边表中的所有项目,即使其中有些项中的数据未填写完全。

左外连接返回那些存在于左表而右表中却没有的行,再加上内连接的行。

4.14.2、右外连接(Right Outer Jion)

包含右边表的全部行(不管左边的表中是否存在与它们匹配的行),以及左边表中全部匹配的行。

select *

from table_1 i right outer join table_2 t

on i.Id = t. Id

4.14.3、全连接

包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。

全外连接返回参与连接的两个数据集合中的全部数据,无论它们是否具有与之相匹配的行。在功能上,它等价于对这两个数据集合分别进行左外连接和右外连接,然后再使用消去重复行的并操作将上述两个结果集合并为一个结果集。

在现实生活中,参照完整性约束可以减少对于全外连接的使用,一般情况下左外连接就足够了。在数据库中没有利用清晰、规范的约束来防范错误数据情况下,全外连接就变得非常有用了,你可以使用它来清理数据库中的数据。

select *

from  table_1 i full outer join table_2 t

on i.Id = t. Id

 

4.14.4、外连接与条件配合使用

内连接查询中加入条件是,无论是将它加入到join子句,还是加入到where子句,其效果是完全一样的.

外连接情况就不同了。当把条件加入到join子句时,SQL ServerInformix会返回外连接表的全部行,然后使用指定的条件返回第二个表的行。如果将条件放到where子句中,SQL Server将会首先进行连接操作,然后使用where子句对连接后的行进行筛选。

下面的两个查询展示了条件放置位子对执行结果的影响:

条件在join子句

select *

from  t_institution i left outer join t_teller t

on i.inst_no = t.inst_no  and i.inst_no = “5801”

结果是:

inst_no    inst_name           inst_no    teller_no  teller_name

5801       天河区               5801       0001       tom

5801       天河区               5801       0002       david

5802       越秀区

5803       白云区

条件在where子句

select *

from  t_institution i left outer join t_teller t

on i.inst_no = t.inst_no

where i.inst_no = “5801”

结果是:

inst_no    inst_name            inst_no    teller_no  teller_name

5801       天河区               5801       0001       tom

5801       天河区               5801       0002       david

4.15、自身连接

自身连接是同一个表自己与自己进行连接。这种一元连接通常用于从自反关系(也称作递归关系)中抽取数据。例如:人力资源数据库中雇员与老板的关系。下面例子是在机构表中查找本机构和上级机构的信息。

select s.inst_no superior_inst, s.inst_name sup_inst_name, i.inst_no, i.inst_name

from t_institution i

join t_institution s

on i.superior_inst = s.inst_no

结果是:

superior_inst   sup_inst_name        inst_no    inst_name

800               广州市                  5801       天河区

800               广州市                  5802       越秀区

800               广州市                  5803       白云区

 

select c1.cno,c1.coursename,c1.pno,c2.coursename

from courses c1,courses c2 where c1.pno=c2.cno

采用别名解决问题。

4.16、交叉连接

交叉连接用于对两个源表进行纯关系代数的乘运算。直接将一个数据源中的每一行与另一个数据源的每一行都一一匹配。例如,如果第一个数据源有5行,而第二个数据源有4行,那交叉连接产生20行。人们将这种类型的结果集称为笛卡尔乘积。

大多数交叉连接都是由于错误操作而造成的;但是它们却非常适合向数据库中填充例子数据,或者预先创建一些空行以便为程序执行期间所要填充的数据保留空间。

select * from  t_institution i cross join t_teller t

在交叉连接中没有on条件子句。

select lastname+firstname from lastname CROSS JOIN firstanme

4.17UNION 运算符

UNION 运算符通过组合其他两个结果表(例如 TABLE1 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2

合并查询结果,如:

SELECT * FROM students WHERE name like ‘%’ UNION [ALL] SELECT * FROM students WHERE name like ‘%’

4.18EXCEPT 运算符

EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。

4.19INTERSECT 运算符

INTERSECT 运算符通过只包括 TABLE1 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。

注:使用运算词的几个查询结果行必须是一致的。

4.20、随即读取数据

select newid()

说明:随机选择记录

select top 10 * from tablename order by newid()

说明:随机取出10条数据

4.21INTO复制表

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

法一:select * into b from a where 1<>1

法二:select top 0 * into b from a

 

4.22SQL Server日期计算

a. (本)月的第一天

SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)

b. 本周的星期一

SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)

c. (本)年的第一天

SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)

d. (本)季度的第一天

SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)

e. 上个月的最后一天

SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0))

f. 去年的最后一天

SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))

g. 本月的最后一天

SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0))

h. 本月的第一个星期一

select DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,6-datepart(day,getdate()),getdate())), 0)

i. 本年的最后一天

SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))

4.23、得到表中最小的未使用的ID

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)

说明:Handle是表明,HandleIDHandle表中表示ID的字段名称。

4.24、列出数据库里所有的表名

select name from sysobjects where type='U'

4.25、显示文章、提交人和最后回复时间

select a.title,a.username,b.adddate

from table a,(select max(adddate) adddate

from table

where table.title=a.title) b

4.26、在线视图查询(表名1a )

select * from (SELECT a,b,c FROM a) t where t.a > 1;

4.27、四表联查问题:

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 .....

4.28、日程安排提前五分钟提醒
SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5

4.29、一条sql 语句搞定数据库分页
select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段

4.30、选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)

select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)

4.31、包括所有在 TableA 中但不在 TableBTableC 中的行并消除所有重复行而派生出一个结果表

(select a from tableA ) except (select a from tableB) except (select a from tableC)

4.32、列出表里的所有的

select name from syscolumns where id=object_id('TableName')

4.33、列示typevenderpcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case

select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0

end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type

显示结果:

type vender pcs

电脑 A 1

电脑 A 1

光盘 B 2

光盘 A 2

手机 B 3

手机 C 3

 

4.34、如何在数据库里找到含有相同字段的表?

a. 查已知列名的情况

SELECT b.name as TableName,a.name as columnname

From syscolumns a INNER JOIN sysobjects b

ON a.id=b.id

AND b.type='U'

AND a.name='你的字段名字'

 

b. 未知列名查所有在不同表出现过的列名
Select o.name As tablename,s1.name As columnname
From syscolumns s1, sysobjects o
Where s1.id = o.id
 And o.type = 'U'
 And Exists (
 Select 1 From syscolumns s2

 Where s1.name = s2.name

 And s1.id <> s2.id

 )

 

4.35、查询数据的最大排序问题(只能用一条语句写)

 

CREATE TABLE hard (qu char (11) ,co char (11) ,je numeric(3, 0))

insert into hard values ('A','1',3)
insert into hard values ('A','2',4)
insert into hard values ('A','4',2)
insert into hard values ('A','6',9)
insert into hard values ('B','1',4)
insert into hard values ('B','2',5)
insert into hard values ('B','3',6)
insert into hard values ('C','3',4)
insert into hard values ('C','6',7)
insert into hard values ('C','2',3)


要求查询出来的结果如下:

qu co je
----------- ----------- -----
A 6 9
A 2 4
B 3 6
B 2 5
C 6 7
C 3 4


就是要按qu分组,每组中取je最大的前2位!!
而且只能用一句sql语句!!!
select * from hard a where je in (select top 2 je from hard b where a.qu=b.qu order by je)

4.36、怎么判断出一个表的哪些字段不允许为空?

select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where IS_NULLABLE='NO' and TABLE_NAME=tablename

4.37、如何在数据库里找到含有相同字段的表?

a. 查已知列名的情况

SELECT b.name as TableName,a.name as columnname

From syscolumns a INNER JOIN sysobjects b

ON a.id=b.id

AND b.type='U'

AND a.name='你的字段名字'

b. 未知列名查所有在不同表出现过的列名

Select o.name As tablename,s1.name As columnname

From syscolumns s1, sysobjects o

Where s1.id = o.id

And o.type = 'U'

And Exists (

Select 1 From syscolumns s2

Where s1.name = s2.name

And s1.id <> s2.id

)

4.38、怎么判断出一个表的哪些字段不允许为空?

select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where IS_NULLABLE='NO' and TABLE_NAME=tablename

4.39、查询第xxx行数据

假设id是主键:
select * from (select top xxx * from yourtable) aa where not exists(select 1 from (select top xxx-1 * from yourtable) bb where aa.id=bb.id)

 

如果使用游标也是可以的
fetch absolute [number] from [cursor_name]
行数为绝对行数

 

4.40、快速获取表test的记录总数[对大容量表非常有效]

快速获取表test的记录总数:
select rows from sysindexes where id = object_id(‘test’) and indid in (0,1)

update 2 set KHXH=(ID+1)\2 2行递增编号
update [23] set id1 = 'No.'+right('00000000'+id,6) where id not like 'No%' //
递增
update [23] set id1= 'No.'+right('00000000'+replace(id1,'No.',''),6) //
补位递增
delete from [1] where (id%2)=1
奇数

替换表名字段
update [1] set domurl = replace(domurl,'Upload/Imgswf/','Upload/Photo/') where domurl like '%Upload/Imgswf/%'

截位
SELECT LEFT(
表名, 5)

 

 

4.41、获取表结构[ 'sysobjects' 替换 成 'tablename' 即可]

SELECT CASE IsNull(I.name, '')
When '' Then ''
Else '*'
End as IsPK,
Object_Name(A.id) as t_name,
A.name as c_name,
IsNull(SubString(M.text, 1, 254), '') as pbc_init,
T.name as F_DataType,
CASE IsNull(TYPEPROPERTY(T.name, 'Scale'), '')
WHEN '' Then Cast(A.prec as varchar)
ELSE Cast(A.prec as varchar) + ',' + Cast(A.scale as varchar)
END as F_Scale,
A.isnullable as F_isNullAble
FROM Syscolumns as A
JOIN Systypes as T
ON (A.xType = T.xUserType AND A.Id = Object_id('sysobjects') )
LEFT JOIN ( SysIndexes as I
JOIN Syscolumns as A1
ON ( I.id = A1.id and A1.id = object_id('sysobjects') and (I.status & 0x800) = 0x800 AND A1.colid <= I.keycnt) )
ON ( A.id = I.id AND A.name = index_col('sysobjects', I.indid, A1.colid) )
LEFT JOIN SysComments as M
ON ( M.id = A.cdefault and ObjectProperty(A.cdefault, 'IsConstraint') = 1 )
ORDER BY A.Colid ASC

4.42、提取数据库内所有表的字段详细说明的SQL语句

SELECT
(case when a.colorder=1 then d.name else '' end) N'
表名',
a.colorder N'
字段序号',
a.name N'
字段名',
(case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '√'else ''
end) N'
标识',
(case when (SELECT count(*)
FROM sysobjects
WHERE (name in
(SELECT name
FROM sysindexes
WHERE (id = a.id) AND (indid in
(SELECT indid
FROM sysindexkeys
WHERE (id = a.id) AND (colid in
(SELECT colid
FROM syscolumns
WHERE (id = a.id) AND (name = a.name))))))) AND
(xtype = 'PK'))>0 then '√' else '' end) N'
主键',
b.name N'
类型',
a.length N'
占用字节数',
COLUMNPROPERTY(a.id,a.name,'PRECISION') as N'
长度',
isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as N'
小数位数',
(case when a.isnullable=1 then '√'else '' end) N'
允许空',
isnull(e.text,'') N'
默认值',
isnull(g.[value],'') AS N'
字段说明'
FROM syscolumns a
left join systypes b
on a.xtype=b.xusertype
inner join sysobjects d
on a.id=d.id and d.xtype='U' and d.name<>'dtproperties'
left join syscomments e
on a.cdefault=e.id
left join sysproperties g
on a.id=g.id AND a.colid = g.smallid
order by object_name(a.id),a.colorder

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

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 性别,生源地,高考总成绩

 

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

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')

 

4.45、一个SQL语句的问题:行列转换

认同与认同
select * from v_temp
上面的视图结果如下:
user_name role_name
-------------------------
系统管理员 管理员
feng
管理员
feng
一般用户
test
一般用户
想把结果变成这样:
user_name role_name
---------------------------
系统管理员 管理员
feng
管理员,一般用户
test
一般用户
===================
create table a_test(name varchar(20),role2 varchar(20))
insert into a_test values('
','管理員')
insert into a_test values('
','管理員')
insert into a_test values('
','一般用戶')
insert into a_test values('
','一般用戶')

create function join_str(@content varchar(100))
returns varchar(2000)
as
begin
declare @str varchar(2000)
set @str=''
select @str=@str+','+rtrim(role2) from a_test where [name]=@content
select @str=right(@str,len(@str)-1)
return @str
end
go

--调用:
select [name],dbo.join_str([name]) role2 from a_test group by [name]

--select distinct name,dbo.uf_test(name) from a_test

4.46、求助!快速比较结构相同的两表
结构相同的两表,一表有记录3万条左右,一表有记录2万条左右,我怎样快速查找两表的不同记录?
============================
给你一个测试方法,从northwind中的orders表取数据。
select * into n1 from orders
select * into n2 from orders

select * from n1
select * from n2

--添加主键,然后修改n1中若干字段的若干条
alter table n1 add constraint pk_n1_id primary key (OrderID)
alter table n2 add constraint pk_n2_id primary key (OrderID)

select OrderID from (select * from n1
union
select * from n2) a group by OrderID having count(*) > 1

应该可以,而且将不同的记录的ID显示出来。
下面的适用于双方记录一样的情况,

select * from n1 where orderid in
(
select OrderID from (select * from n1
union
select * from n2) a group by OrderID having count(*) > 1
)
至于双方互不存在的记录是比较好处理的
--
删除n1,n2中若干条记录
delete from n1 where orderID in ('10728','10730')
delete from n2 where orderID in ('11000','11001')

--*************************************************************
--
双方都有该记录却不完全相同
select * from n1 where orderid in
(
select OrderID from (select * from n1
union
select * from n2) a group by OrderID having count(*) > 1
)
union
--n2
中存在但在n1中不存的在10728,10730
select * from n1 where OrderID not in (select OrderID from n2)
union
--n1
中存在但在n2中不存的在11000,11001
select * from n2 where OrderID not in (select OrderID from n1)

 

三、存储过程

1. 1=11=2的使用,在SQL语句组合时用的较多

“where 1=1” 是表示选择全部   “where 1=2”全部不选,
如:
if @strWhere !=''

Begin

set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere
end
else
begin
set @strSQL = 'select count(*) as Total from [' + @tblName + ']'
end

我们可以直接写成
set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1
安定 '+ @strWhere

2. SQL SERVER中直接循环写入数据

declare @i int
set @i=1
while @i<30
begin
   insert into test (userid) values(@i)
   set @i=@i+1
end

 

3. 小记存储过程中经常用到的本周,本月,本年函数

Dateadd(wk,datediff(wk,0,getdate()),-1)
Dateadd(wk,datediff(wk,0,getdate()),6)

Dateadd(mm,datediff(mm,0,getdate()),0)
Dateadd(ms,-3,dateadd(mm,datediff(m,0,getdate())+1,0))

Dateadd(yy,datediff(yy,0,getdate()),0)
Dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))

上面的SQL代码只是一个时间段
Dateadd(wk,datediff(wk,0,getdate()),-1)
Dateadd(wk,datediff(wk,0,getdate()),6)
就是表示本周时间段.
下面的SQL的条件部分,就是查询时间段在本周范围内的:
Where Time BETWEEN Dateadd(wk,datediff(wk,0,getdate()),-1) AND Dateadd(wk,datediff(wk,0,getdate()),6)
而在存储过程中
select @begintime = Dateadd(wk,datediff(wk,0,getdate()),-1)
select @endtime = Dateadd(wk,datediff(wk,0,getdate()),6)

4.如何删除一个表中重复的记录?

create table a_dist(id int,name varchar(20))

insert into a_dist values(1,'abc')
insert into a_dist values(1,'abc')
insert into a_dist values(1,'abc')
insert into a_dist values(1,'abc')

exec up_distinct 'a_dist','id'

select * from a_dist

create procedure up_distinct(@t_name varchar(30),@f_key varchar(30))
--f_key
表示是分組字段﹐即主鍵字段
as
begin
declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer
select @sql = 'declare cur_rows cursor for select '+@f_key+' ,count(*) from ' +@t_name +' group by ' +@f_key +' having count(*) > 1'
exec(@sql)
open cur_rows
fetch cur_rows into @id,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
select @type = xtype from syscolumns where id=object_id(@t_name) and name=@f_key
if @type=56
select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id
if @type=167
select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+''''+ @id +''''
exec(@sql)
fetch cur_rows into @id,@max
end
close cur_rows
deallocate cur_rows
set rowcount 0
end

select * from systypes
select * from syscolumns where id = object_id('a_dist')

 

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

9.5.求删除重复记录的sql语句?
怎样把具有相同字段的纪录删除,只留下一条。
例如,表test里有id,name字段
如果有name相同的记录 只留下一条,其余的删除。
name
的内容不定,相同的记录数不定。
有没有这样的sql语句?
==============================
A:
一个完整的解决方案:

将重复的记录记入temp1:
select [
标志字段id],count(*) into temp1 from [表名]
group by [
标志字段id]
having count(*)>1

2、将不重复的记录记入temp1:
insert temp1
select [
标志字段id],count(*) from [表名]
group by [
标志字段id]
having count(*)=1

3、作一个包含所有不重复记录的表:
select * into temp2 from [
表名]
where
标志字段id in(select 标志字段id from temp1)

4、删除重复表:
delete [表名]

5、恢复表:
insert [表名]
select * from temp2

================================
B:
create table a_dist(id int,name varchar(20))

insert into a_dist values(1,'abc')
insert into a_dist values(1,'abc')
insert into a_dist values(1,'abc')
insert into a_dist values(1,'abc')

exec up_distinct 'a_dist','id'

select * from a_dist

create procedure up_distinct(@t_name varchar(30),@f_key varchar(30))
--f_key
表示是分組字段﹐即主鍵字段
as
begin
declare @max integer,@id varchar(30) ,@sql varchar(7999) ,@type integer
select @sql = 'declare cur_rows cursor for select '+@f_key+' ,count(*) from ' +@t_name +' group by ' +@f_key +' having count(*) > 1'
exec(@sql)
open cur_rows
fetch cur_rows into @id,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
select @type = xtype from syscolumns where id=object_id(@t_name) and name=@f_key
if @type=56
select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+ @id
if @type=167
select @sql = 'delete from '+@t_name+' where ' + @f_key+' = '+''''+ @id +''''
exec(@sql)
fetch cur_rows into @id,@max
end
close cur_rows
deallocate cur_rows
set rowcount 0
end

select * from systypes
select * from syscolumns where id = object_id('a_dist')

 

5. 行列转换--普通

 

假设有张学生成绩表(CJ)如下
Name Subject Result
张三 语文 80
张三 数学 90
张三 物理 85
李四 语文 85
李四 数学 92
李四 物理 82

想变成
姓名 语文 数学 物理
张三 80 90 85
李四 85 92 82

declare @sql varchar(4000)
set @sql = 'select Name'
select @sql = @sql + ',sum(case Subject when '''+Subject+''' then Result end) ['+Subject+']'
from (select distinct Subject from CJ) as a
select @sql = @sql+' from test group by name'
exec(@sql)

 

 

 

6. 行列转换--合并

 

有表A,
id pid
1 1
1 2
1 3
2 1
2 2
3 1
如何化成表B:
id pid
1 1,2,3
2 1,2
3 1

创建一个合并的函数
create function fmerg(@id int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str=''
select @str=@str+','+cast(pid as varchar) from
A where id=@id
set @str=right(@str,len(@str)-1)
return(@str)
End
go

--调用自定义函数得到结果
select distinct id,dbo.fmerg(id) from
A

 

 

 

7. 如何取得一个数据表的所有列名

 

方法如下:先从SYSTEMOBJECT系统表中取得数据表的SYSTEMID,然后再SYSCOLUMN表中取得该数据表的所有列名。
SQL
语句如下:
declare @objid int,@objname char(40)
set @objname = 'tablename'
select @objid = id from sysobjects where id = object_id(@objname)
select 'Column_name' = name from syscolumns where id = @objid order by colid

 

8.

 

 

9.

 

 

10.

 

上个周六的时候去金蝶面试,出了这样一道SQL题,共享之
给下面这样的一个表记录:

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

购物人      商品名称     数量

A                      2

B                      4

C                      1

A                      2

B                      5

给出所有购入商品为两种或两种以上购物人记录。

 

如果数据库记录中有这样的记录:

A                      2

A                      4

A                      3则会出现错误,命名为是否错误

 

 

 

众大侠答案

答案1

我给的SQL是这样的,调试是对的,但总感觉到有些别扭

select 购物人 from   group by 购物人 having count(商品名称)>=2

我的分析:

SQL语句分析:按照购物人分组,每一组信息条数大于等于2,。

错误分析:(1)只查找出了“购物人”这一字段信息

2是否错误错误的分析

答案2

购物人记录购物人是有区别的,如果主考官要考查这一点,你没戏了!

select 购物人,count(商品名称) from group by 购物人 having count(商品名称)>=2

我的分析:

SQL语句分析:按照购物人分组,每一组信息条数大于等于2

错误分析:(1)只找出来“购物人”、“商品种类数”两项信息。

2是否错误错误的分析

 

答案3

题目是

-给出所有购入商品为两种或两种以上的购物人记录

-给出购入商品的记录

-给出记录

样表中的顾客B购买了二种商品(乙、丙),符合要求,所以将顾客B的所有购物记录列出

select * from where 购物人 in (select 购物人 from group by 购物人 having count(商品名称)>=2)

 

我的分析:

SQL语句分析:列出了所有买过两次东西的人的记录。

错误分析:(1是否错误错误的分析

 

答案4

select distinct 购物人 from (select 购物人,商品名称 from group by 购物人,商品名称 having count(*)>=2)

我的分析:找出了有两行以上购物人的记录,按照购物人,商品名称两个字段排序,

错误分析:(1是否错误错误的分析

 

答案5

select * from where 购物人 in (select distinct 购物人,商品名称 from group by 购物人 having count(商品名称)>=2);

 

是否错误错误的分析

 

 

答案6

select * from where 购物人 in (select 购物人 from group by 购物人 having count(商品名称)>=2)

是否错误错误的分析

 

答案7

应该是......having count(distinct 商品名称)>=2 吧。

是否错误错误的分析

 

 

 

 

A:什么是视图:
视图(view):从一个或几个基本表中根据用户需要而做成一个虚表
    1:
视图是虚表,它在存储时只存储视图的定义,而没有存储对应的数据
    2:
视图只在刚刚打开的一瞬间,通过定义从基表中搜集数据,并展现给用户

B:视图与查询的区别:
视图和查询都是用由sql语句组成,这是他们相同的地方,但是视图和查询有着本质区别:
它们的区别在于:1:存储上的区别:视图存储为数据库设计的一部分,而查询则不是.
              2:
更新限制的要求不一样
               
要注意:因为视图来自于表,所以通过视图可以间接对表进行更新,我们也可以通过update语句对表进行更新,但是对视图和查询更新限制是不同的,以下我们会知道虽然通过视图可以间接更新表但是有很多限制.
              3:
排序结果:通过sql语句,可以对一个表进行排序,而视图则不行.
               
比如:创建一个含有order by子句的视图,看一下可以成功吗?

C:视图的优点
为什么有了表还要引入视图呢?这是因为视图具有以下几个优点:
1:
能分割数据,简化观点
 
可以通过selectwhere来定义视图,从而可以分割数据基表中某些对于用户不关心的数据,使用户把注意力集中到所关心的数据列.进一步简化浏览数据工作.
2:
为数据提供一定的逻辑独立性
 
如果为某一个基表定义一个视图,即使以后基本表的内容的发生改变了也不会影响视图定义所得到的数据
3:
提供自动的安全保护功能
 
视图能像基本表一样授予或撤消访问许可权.
4:
视图可以间接对表进行更新,因此视图的更新就是表的更新

D:视图的创建和管理
  视图的创建
  1:
通过sql语句
   
格式:create view 视图名 as select 语句
        
试一试:分别创建关于一个表或多个表的视图[因为视图可以来自于多表]
  2:
通过企业管理器  
   
说明:1:在完成视图的创立之后,就可以像使用基本表一样来使用视图
         2:
在创建视图时,并非所有的select子查询都可用
          
:computecompute by,order by[除非与top一起连用
         3:
但在查询时,依然都可以用在创建时禁用的select子查询
         4:
在视图创建时,必须为没有标题列指定标题[思考:能否不用select语句来创建一个视图]
 
 
视图的删除:
  1:
通过sql语句:drop view 视图名
  2:
通过企业管理器
   
说明:与删除表不同的是,删除视图后只是删除了视图了定义,并没有删除表中的数据.[查看相关性]
 
 
修改视图的定义
  1:
通过企业管理器
  2:
通过sql语句:
   
格式:alter view 视图名 as 新的select语句

浏览视图信息 sp_helptext 视图名 [查看视图创建的语句]

E:如何通过视图修改基本表的数据.
  1:在视图上使用insert语句
   
通过视图插入数据与直接在表中插入数据一样,但视图毕竟不是基本表.因此在进行数据插入时还是有一定的限制
      1:
如果视图上没有包括基本表中属性为not null[不能为空]的列,那么插入操作会因为那些列是null值而失败.
      2:
如果某些列因为某些规则或约束的限制而不能直接接受从视图插入的列时,插入会失败
      3:
如果在视图中包含了使用统计函数的结果,或是包含计算列,则插入操作会失败
      4:
不能在使用了distinct语句的视图中插入值
      5:
不能在使用了group by语句的视图中插入值

  2:使用update更新视图中的数据
       1:
更新视图与更新表格一样,但是在视图中使用了多个基本表连接的情况下,每次更新操作只能更新来自基本表的一个数据列
        
例如:创建以下视图:create view del as
                          select
职工号,姓名,部门名称,负责人 from work1,部门
                          where work1.
部门编号=部门.部门编号
             
如果再执行下面的语句时:
                        update del set
职工号=\'001\',部门名称=\'wenda\' where 职工号=\'01\'[出现错误]
             
只能够改成:update del set 职工号=\'001\' where 职工号=\'01\'
                        update del set
部门名称=\'wenda\' where 职工号=\'01\'
       2:
不能在使用了distinct语句的视图中更新值
       3:
不能在使用了group by语句的视图中更新值
 
  3:
使用delete删除视图中数据.
   
通过视图删除数据最终体现为从基本表中删除数据
   
格式:delete 视图名 [where 条件]
   
说明:当视图由两个以上的基表构成时,不允许删除视图的数据
   
例如:建一个视图kk
         create view kk as
         select
职工号,姓名,性别,部门名称 from work1,部门 where work1.部门编号=部门.部门编号 [试着去删除]

    使用with check option的视图
   
如果不了解视图定义内容,则常常会发生向视图中输入不符合视图定义的数据的情况.
   
比如:create view xm as
         select * from work where
性别=\'\'
        
完全可以插入insert xm values(\'001\',\'\',23,\'2400\'....)
尽管从意义上来说是不合理的,但是上述语句是正确的.为了防止这种情况的发生,可以使用with check option子句来对插入的或更改的数据进行限制.
   
比如:create view xm as
         select * from work where
性别=\'\' with check option

    使用schemabinding的视图[使用绑定到构架]
我们知道视图是依赖于表,如果在一个表中创建一个视图,今后如果这个表被删除了,则这个视图将不可再用了.为了防止用户删除一个有视图在引用的表,可以在创建视图的时候加上schemabinding关键字.
   
比如:create view 基本工资 with SCHEMABINDING
         as select
姓名,性别,基本工资 from dbo.work
   
说明:1:不能使用“*”来创建此类型的视图
         2:
创建此类型的视图时,一定要加上dbo.表名.
         3:
如果在某个表中定义了此类视图,则用户将不能对表的结构进行修改,否则会删除这些绑定
         4:
如果用户对表的结构进行列改名,则会删除绑定而且视图不可用.
         5:
如果用户对表的结构进行列的类型或者大小修改,则会删除绑定但视图可用,此时用户可以删除视图所引用的表.
  
   
使用with encryption对视图进行加密
为了保护创建视图定义的原代码,可以对视图进行加密.
   
比如:create view kk with encryption
         as select * from work where
职称=\'经理\'
   
sp_helptext来查看一下.或用企业管理器查看一下.
   
说明:如果应用此项用户将无法设计视图

F:使用视图加强数据的安全
 
一般通过使用视图共有三种途径加强数据的安全性    
     A:
对不同用户授予不同的使用权.
     B:
通过使用select子句限制用户对某些底层基表的列的访问
     C:
通过使用where子句限制用户对某些底层基表的行的访问
 
对不同用户授予不同的权限

 

 

注:其他DateTime操作语法 (转)

1、日期格式化处理
DECLARE @dt datetime
SET @dt=GETDATE()
--1
.短日期格式:yyyy-m-d
SELECT REPLACE(CONVERT(varchar(10),@dt,120),N'-0','-')
--2
.长日期格式:yyyymmdd
--A.
方法1
SELECT STUFF(STUFF(CONVERT(char(8),@dt,112),5,0,N'
'),8,0,N'')+N''
--B.
方法2
SELECT DATENAME(Year,@dt)+N'
'+DATENAME(Month,@dt)+N''+DATENAME(Day,@dt)+N''
--3
.长日期格式:yyyymd
SELECT DATENAME(Year,@dt)+N'
'+CAST(DATEPART(Month,@dt) AS varchar)+N''+DATENAME(Day,@dt)+N''
--4.
完整日期+时间格式:yyyy-mm-dd hh:mi:ss:mmm
SELECT CONVERT(char(11),@dt,120)+CONVERT(char(12),@dt,114)
2
、日期推算处理
DECLARE @dt datetime
SET @dt=GETDATE()
DECLARE @number int
SET @number=3
--1
.指定日期该年的第一天或最后一天
--A.
年的第一天
SELECT CONVERT(char(5),@dt,120)+'1-1'
--B.
年的最后一天
SELECT CONVERT(char(5),@dt,120)+'12-31'
--2
.指定日期所在季度的第一天或最后一天
--A.
季度的第一天
SELECT CONVERT(datetime,
CONVERT(char(8),
DATEADD(Month,
DATEPART(Quarter,@dt)*3-Month(@dt)-2,
@dt),
120)+'1')
--B.
季度的最后一天(CASE判断法)
SELECT CONVERT(datetime,
CONVERT(char(8),
DATEADD(Month,
DATEPART(Quarter,@dt)*3-Month(@dt),
@dt),
120)
+CASE WHEN DATEPART(Quarter,@dt) in(1,4)
THEN '31'ELSE '30' END)
--C.
季度的最后一天(直接推算法)
SELECT DATEADD(Day,-1,
CONVERT(char(8),
DATEADD(Month,
1+DATEPART(Quarter,@dt)*3-Month(@dt),
@dt),
120)+'1')
--3
.指定日期所在月份的第一天或最后一天
--A.
月的第一天
SELECT CONVERT(datetime,CONVERT(char(8),@dt,120)+'1')
--B.
月的最后一天
SELECT DATEADD(Day,-1,CONVERT(char(8),DATEADD(Month,1,@dt),120)+'1')
--C.
月的最后一天(容易使用的错误方法)
SELECT DATEADD(Month,1,DATEADD(Day,-DAY(@dt),@dt))
--4
.指定日期所在周的任意一天
SELECT DATEADD(Day,@number-DATEPART(Weekday,@dt),@dt)
--5
.指定日期所在周的任意星期几
--A. 
星期天做为一周的第1
SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFIRST-1)%7,@dt)
--B. 
星期一做为一周的第1
SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFIRST-2)%7-1,@dt) 

 

posted @ 2009-06-12 09:13  jianlinglo  阅读(1167)  评论(0编辑  收藏  举报