什么是SQL表达式?在SQL语句中,表达式可以是函数,也可以是列和列之间的混合运算。
很多时候,对于表达式的使用,可以比单独操作表上的列,带来更多方便。
一. 在HAVING中使用表达式
--
drop table t
create
table
t(c1
int
,c2
int
)
insert
into
t
select
1
,
100
union
all
select
1
,
200
union
all
select
2
,
100
union
all
select
2
,
200
union
all
select
2
,
300
union
all
select
3
,
50
union
all
select
3
,
200
union
all
select
4
,
50
union
all
select
4
,
200
union
all
select
4
,
300
返回c1,满足:有3个且都大于等于100 的c2 (学校的考试题中很多见)。
select
c1
from
t
group
by
c1
having
min
(c2)
>=
100
and
count
(
1
)
=
3
同样,表达式也可以用于group by 子句。
二. 在ORDER BY中使用表达式
--
drop table t_orderby
create
table
t_orderby
(
c1
int
null
,
c2
varchar
(
10
)
null
,
c3
varchar
(
10
)
null
)
insert
into
t_orderby
select
1
,
'
2
'
,
'
a1
'
union
all
select
1
,
'
1
'
,
'
a2
'
union
all
select
3
,
'
1
'
,
'
ab
'
union
all
select
1
,
'
4
'
,
'
b1
'
1. c2列的数据按'4','1','2'的指定顺序排序
(1) 使用union
select
*
from
t_orderby
where
c2
=
'
4
'
union
all
select
*
from
t_orderby
where
c2
=
'
1
'
union
all
select
*
from
t_orderby
where
c2
=
'
2
'
(2) 使用表达式方法1
select
*
from
t_orderby
order
by
charindex
(c2,
'
4,1,2
'
)
(3) 使用表达式方法2 ,再加个按照c1倒序
select
*
from
t_orderby
order
by
case
when
c2
=
'
4
'
then
1
when
c2
=
'
1
'
then
2
when
c2
=
'
2
'
then
3
end
,c1
desc
2. 随机排序
(1) 要求c2='4'排第一行,其他的行随机排序
select
*
from
t_orderby
order
by
case
when
c2
=
'
4
'
then
1
else
1
+
rand
()
end
(2) 所有行随机排序
select
*
from
t_orderby
order
by
newid
()
(3) 随机取出第一行
select
top
1
*
from
t_orderby
order
by
newid
()
3. 要求列c3中数据,先按第一个字符排序,再按第二个字符排序
select
*
from
t_orderby
order
by
left
(c3,
1
),
ASCII
(
substring
(c3,
2
,
1
))
三. 在COUNT中使用表达式
--
drop table t_count
create
table
t_count
(
c1
varchar
(
10
)
null
,
c2
varchar
(
10
)
null
)
insert
into
t_count
values
(
null
,
null
)
insert
into
t_count
values
(
'
a
'
,
'
b
'
)
insert
into
t_count
values
(
'
a
'
,
'
b
'
)
insert
into
t_count
values
(
'
c
'
,
'
d
'
)
1. 使用常量表达式避免忽略NULL值
select
COUNT
(c1)
from
t_count
--
3
select
COUNT
(
distinct
c1)
from
t_count
--
2
聚合函数中, SUM/AVG/COUNT中的NULL会被忽略,比如:这里的count(c1)忽略了null
select
COUNT
(
*
)
from
t_count
--
4
select
COUNT
(
1
)
from
t_count
--
4
select
COUNT
(
1000
)
from
t_count
--
4
用count(*)不会忽略NULL,同样用count(1)也不会忽略NULL,这里的1就是一个常量表达式,换成其他常量表达式也可以,比如count(1000)。
另外,count(1)和order by 1,2那里的数字意思不一样,order by后面的序号表示列号。
2. 小心表达式值为NULL被忽略
--
正常
select
count
(
*
)
from
(
select
c1,c2
from
t_count
group
by
c1,c2) t
--
3
select
count
(
*
)
from
(
select
distinct
c1,c2
from
t_count) t
--
3
--
有NULL参与了运算,所以表达式值为NULL
select
count
(
distinct
c1
+
c2)
from
t_count
--
2
四. 在JOIN中使用表达式
--
drop table t1,t2
create
table
t1
(
url
varchar
(
1000
)
)
create
table
t2
(
code
varchar
(
1000
)
)
--
insert
insert
into
t1
select
'
http://www.baidu.com/test1
'
union
all
select
'
http://www.baidu.com/test2
'
union
all
select
'
http://www.baidu.com/test3
'
union
all
select
'
www.baidu.com/test1
'
union
all
select
'
www.baidu.com/test2
'
union
all
select
'
http://www.google.com/test1
'
union
all
select
'
http://www.google.com/test2
'
union
all
select
'
http://www.sogou.com/test3
'
union
all
select
'
http://www.sogou.com/test4
'
insert
into
t2
select
'
baidu.com
'
union
all
select
'
sogou.com
'
要求t1,t2表的两个列之间做匹配,t2的列值包含在t1的列值里。
事实上,在join或者where条件中,只要能构造出比较运算表达式(返回boolean值),就可以用作判断条件。
select
t2.code,t1.url
from
t1
inner
join
t2
on
CHARINDEX
(t2.code,t1.url)
>
0
--
结果如下
/*
baidu.com http://www.baidu.com/test1
baidu.com http://www.baidu.com/test2
baidu.com http://www.baidu.com/test3
baidu.com www.baidu.com/test1
baidu.com www.baidu.com/test2
sogou.com http://www.sogou.com/test3
sogou.com http://www.sogou.com/test4
*/

