Sql server 选择SQL Server中的前1名
请帮我选择第一名 像这样的数据Sql server 选择SQL Server中的前1名,sql-server,Sql Server,请帮我选择第一名 像这样的数据 Code Amp Price ----------------------- 00001 10 1000 00002 75-100 1500 00003 50-60 1200 00004 15 1100 注:列Amp的数据类型为VarChar 我想选择放大器75,我想得到的价格是1500 所以我用这句话: SELECT TOP 1 * FROM Cable WHERE (Amp <= '
Code Amp Price
-----------------------
00001 10 1000
00002 75-100 1500
00003 50-60 1200
00004 15 1100
注:列Amp的数据类型为VarChar
我想选择放大器75,我想得到的价格是1500
所以我用这句话:
SELECT TOP 1 *
FROM Cable
WHERE (Amp <= '75')
ORDER BY Amp DESC
但是我得到的结果价格是1200,是错误的记录,代码是00003,实际上我想要的结果是代码:00002,价格是1500
但如果我想使用Amp 76进行选择,则语法为:
SELECT TOP 1 *
FROM Cable
WHERE (Amp <= '75')
ORDER BY Amp DESC
我的案例的真实选择是什么?如果您使用的是SQL Server 2008及更高版本,请帮助我,请尝试以下操作:
SELECT TOP 1 *
FROM Cable
WHERE isnumeric(left(Amp, 2)) = 1 and cast(left(Amp, 2) as int) <= 75
and Price = 1500
ORDER BY Amp DESC
注意:只有当您没有Amp小于10的记录时,这才有效。如果您必须使用此现有数据类型和表结构,则下面的查询可能适用于您
SELECT TOP 1 *
FROM Cable
WHERE (SUBSTRING(Amp,1,IIF((CHARINDEX('-',Amp)-1)>0,(CHARINDEX('-',Amp)-1),0 ) ) <=75)
ORDER BY Amp DESC
几乎任何解析/拆分函数都可以,再加上交叉应用,这就成了一件小事 -无需解析函数即可轻松完成
Declare @Cable table (Code varchar(25),Amp varchar(50),Price int)
Insert Into @Cable values
('00001','10', 1000),
('00002','75-100',1500),
('00003','50-60', 1200),
('00004','15', 1100)
Select Top 1 A.*
From @Cable A
Cross Apply [dbo].[udf-Str-Parse](A.Amp,'-') B
Where RetVal<=76 --<< Notice we are testing for 76
Order By Price Desc
UDF如果感兴趣
问题是SQLServer不会像int那样对varchar列进行排序 排序问题示例: 1小于2是每个nbr中的第一个字符,因此它将进行排序,认为125<24不是真的,尽管对于任何人来说,24应该首先出现看起来都很简单,如果列的数据类型是int,那么这就是它的排序方式 需要做的是将amp列拆分为范围,或max和min。使用-作为delimeter,您可以使用charindex将数字拆分为int 示例数据设置: 答复:
在那之后,where子句中的一个简单的中间约束就可以了。谢谢所有的答案。我决定键入所有数据并使用两个字段对其进行更改 代码Amp1 Amp2价格 000011010000 00002 75 100 1500 00003 50 60 1200 00004151100 我在字段Amp2中键入相同的单个值,然后使用以下语法:
从Amp1和Amp2之间的电缆中选择*这不是存储数据的正确方法。规范化iti我不知道存储数据的方法。但情况是这样的。数据类型问题。。。varchar是字母数字。。把它作为一个数字来排列是不行的。把你的放大器从一个到另一个,从一个到另一个。。。这就是你的数字范围。让你目前的方法更糟糕的是,你把范围和单个数字混在一起。这意味着解决方案将非常困难。您应该认真规范您的数据。先生,您能告诉我您使用的是什么sql server吗?为什么我在charindex中出错?我是在2012年这样做的。您使用的是哪个版本?如果是在2012年之前,那么查询需要一些更改。我仍然使用sql 2000。John | | Cappelletti | was | | here??LOL@GurV他妈的直截了当@古尔夫真的大声吼了出来。。。谢谢你@闪烁不是更好,只是不同。。。这就是说,您有一个语法问题isnumeric…=1,并且您只捕获了left2。当安培范围为150-300时会发生什么?先生,如果你认为我必须为我的案例做些什么?我将尝试更改字段。并非所有的值都像这个75-100,只有很少的数据像条件。很多数据只有一个值,比如1040100ETCMY答案在这两种情况下都有效。如果您的数据是数字10或范围40-90,它将起作用
Code Amp Price
00002 75-100 1500
CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(25))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 a,cte1 b,cte1 c,cte1 d) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(@Delimiter) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter)) = @Delimiter),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter,@String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By A.N)
,RetVal = LTrim(RTrim(Substring(@String, A.N, A.L)))
From cte4 A
);
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/
--Much faster than str-Parse, but limited to 8K
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')
select *
from (
select '125' as nbr
union all
select '24' as nbr
) as a
order by a.nbr asc
declare @cable table
(
code char(5) not null
, amp varchar(10) not null
, price int not null
)
insert into @cable
values
('00001','10' ,10000),
('00002','75-100' ,15000),
('00003','50-60' ,12000),
('00004','15' ,11000)
declare @amp_nbr int = 75
select top 1 *
from (
select c.code
, cast(iif(charindex('-', c.amp, 0) > 0, left(c.amp, charindex('-', c.amp, 0) - 1), c.amp) as int) as amp_min
, cast(iif(charindex('-', c.amp, 0) > 0, right(c.amp, len(c.amp) - charindex('-', c.amp, 0)), c.amp) as int) as amp_max
, c.price
from @cable as c
) as a
where 1=1
and @amp_nbr between a.amp_min and a.amp_max
order by a.amp_min desc