注册 登录
编程论坛 SQL Server论坛

论坛里看到横向求最小值的 SQL Server 语句,求高手解释下什么原理,谢谢啦!

dqk911 发布于 2015-01-07 16:40, 769 次点击
表:
ID      price1   price2  price3
19415    61       90      90
03892    60       72      85
05749    60       120     190
06166    60       178     394
06447    60       124     224

题目:求横向的最小值。
答案:
select [ID],
       [MINIPrice]=(select min([price1])
              from (select [price1]
                  union all select [price2]
                  union all select [price3]
                  union all select [price4])T)
from table


求高手解析下答案,谢谢啦!

比如,这里用了union链接多个表,select后面为什么没有from,还有这里只用了1个min函数为什么能求多行的最小值。刚学sql,还请大神传授。

[ 本帖最后由 dqk911 于 2015-1-7 16:42 编辑 ]
5 回复
#2
tlliqi2015-01-08 09:23
你这能出来正确结果么?
#3
mxbing19842015-01-08 09:52
能啊,我试过了
首先.你执行
Select *,(Select price1) As A From [table]这句
看看效果,其实就是把price1列复制成了A列,及可理解为(Select price1 ) As A 得到的是当前记录的price1值
分析你的SQL
1.
select [price1]
union all select [price2]
union all select [price3]
union all select [price4]
这是把当前记录的price1到4合并成一个1列4行的表,字段名为price1
2.
select min([price1])
              from (上面部分的代码)T
这就是对from部分(也就是1产生的表求最小值)
3.
[MINIPrice]=()
这是把min的结果取个字段名

结合在一起就是,把当前记录的price1到4用union all 拼成一个表(取名T),然后取得这个表的最小值并命名为MINIPrice
#4
dqk9112015-01-12 22:10
回复 3楼 mxbing1984
谢谢版主的答复,学到了很多,还是有地方不理解,把当前记录的price1到4用union all 拼成一个表(取名T),然后取得这个表的最小值并命名为MINIPrice,是否能这么理解
select min([price1])
from (select [price1] from table1
union all select [price2]  from table1
union all select [price3] from table1)T
可这么理解,最后出来的最小值是不是1行1个最小值?

原代码
select [ID],
(select min([price1])
from (select [price1]
union all select [price2]
union all select [price3])T) AS [MINIPrice]
from table1
为什么能出来的是所有行的,不同的横向最小值。

贴出试运行代码如下:
use tempdb
go
create table table1 (ID int,price1 int,price2 int,price3 int)
insert table1 select 1,61,90,90
insert table1 select 2,601,72,85
insert table1 select 3,601,120,190
go

select [ID],
(select min([price1])
from (select [price1]
union all select [price2]
union all select [price3])T) AS MINIPrice
from table1
(原代码,出来结果统计所有行横向最小值)

--select [ID],
--(select min([price1])
--from (select [price1] from table1
--union all select [price2]  from table1
--union all select [price3] from table1)T )AS MINIPrice
--from table1
(这段按我理解的改的,出来的是3行同一个值,为什么呢?)

drop table table1

[ 本帖最后由 dqk911 于 2015-1-12 22:12 编辑 ]
#5
mxbing19842015-01-13 09:06
理解是正确的,但你那样写是不对的,你那样是把表table的price1到3组合成一个表,然后求最小值,结果当然只有一个值咯
这样写就对了,用Where  ID=A.ID 取出当前记录
Select [ID],
(
    Select min([price1])
        From (
            Select [price1] From table1 Where  ID=A.ID
            union all
            Select [price2] From table1 Where  ID=A.ID
            union all
            Select [price3] From table1 Where  ID=A.ID
            )T
)AS MINIPrice
From table1 A

还可以这样写
Select id,MIN(price1) From
(
Select id,price1 From table1
union all
Select id,price2 From table1
union all
Select id,price3 From table1
) s
Group By id
#6
dqk9112015-01-13 18:26
回复 5楼 mxbing1984
谢谢版主,解释的这么详细,下面的例子看懂了,上面那个没完全看懂,我慢慢研究吧,谢谢啦!
1