考虑下表及其记录
create table dbo.test
(
id numeric(4),
vals nvarchar(1000)
);
insert into dbo.test values (1,'1,2,3,4,5');
insert into dbo.test values (2,'6,7,8,9,0');
insert into dbo.test values (3,'11,54,76,23');
我将使用以下功能分割CSV,您可以使用任何方法来帮助select
语法
CREATE FUNCTION [aml].[Split](@String varchar(8000), @Delimiter char(1))
returns @temptable TABLE (items varchar(8000))
as
begin
declare @idx int
declare @slice varchar(8000)
select @idx = 1
if len(@String)<1 or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(Items) values(@slice)
set @String = right(@String,len(@String) - @idx)
if len(@String) = 0 break
end
return
end
我想从id
中为每条记录选择max
和min
以及vals
值。
更新虽然我在SQL Server 2008上编写查询但我需要支持SQL Server 2005及更高版本
答案 0 :(得分:4)
您可以CROSS APPLY
到函数投影的表格,然后在每个id
组上应用常规聚合函数:
SELECT t.id, MIN(CAST(x.items AS INT)) AS MinItem, MAX(CAST(x.items AS INT)) AS MaxItem
FROM dbo.test t
CROSS APPLY dbo.Split(t.vals, ',') x
GROUP BY t.id;
(修改 - 由于这些似乎是整数,因此您需要在应用MIN / MAX
聚合之前进行投射,否则您将获得字母数字排序)
另一种选择是在对它们应用查询之前将逗号分隔列表保留在规范化表结构中 - 将非规范化数据存储在RDBMS中是没有用的:)
答案 1 :(得分:3)
没有功能,只需sql
:
SELECT t.id,
Max(Split.a.value('.', 'VARCHAR(100)')) AS MaxVal,
Min(Split.a.value('.', 'VARCHAR(100)')) AS MinVal
FROM
(
SELECT id,
CAST ('<M>' + REPLACE(vals, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM test
) AS t CROSS APPLY Data.nodes ('/M') AS Split(a)
group by t.id
答案 2 :(得分:0)
选择A.id,(从dbo.Split中选择max(item)(A.vals,&#39;,&#39;))作为maxvalue,(从dbo.Split中选择min(item)(A。 vals,&#39;,#);)作为测试A的最小值
为fplit创建函数 创造功能分裂( @InputString VARCHAR(8000), @Delimiter VARCHAR(50) )
RETURNS @Items TABLE( 物品VARCHAR(8000) )
AS 开始 如果@Delimiter =&#39; &#39; 开始 SET @Delimiter =&#39;,&#39; SET @InputString = REPLACE(@InputString,&#39;&#39;,@ Delimiter) END
IF (@Delimiter IS NULL OR @Delimiter = '')
SET @Delimiter = ','
- INSERT INTO @Items VALUES(@Delimiter) - 诊断 --INSERT INTO @Items VALUES(@InputString) - 诊断
DECLARE @Item VARCHAR(8000)
DECLARE @ItemList VARCHAR(8000)
DECLARE @DelimIndex INT
SET @ItemList = @InputString
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
WHILE (@DelimIndex != 0)
BEGIN
SET @Item = SUBSTRING(@ItemList, 0, @DelimIndex)
INSERT INTO @Items VALUES (@Item)
-- Set @ItemList = @ItemList minus one less item
SET @ItemList = SUBSTRING(@ItemList, @DelimIndex+1, LEN(@ItemList)-@DelimIndex)
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
END -- End WHILE
IF @Item IS NOT NULL -- At least one delimiter was encountered in @InputString
BEGIN
SET @Item = @ItemList
INSERT INTO @Items VALUES (@Item)
END
-- No delimiters were encountered in @InputString, so just return @InputString
ELSE INSERT INTO @Items VALUES (@InputString)
RETURN
结束 - 结束功能 GO