问题描述
- 求个SQL 写法,万分感谢
-
我想实现如下的描述效果:
查询ReferralPath 字段,里面 4 这个数字的位置,按照 '|' 来分割
比如4在 ReferralPath 第一个的位置,结果应该是UserID=7和8的2条记录
4在ReferralPath 第二个的位置, 结果应该是UserID=9和12的2条记录
4在ReferralPath 第三个的位置, 结果应该是UserID=5和10和11 的3条记录
求MSSQL实现方法,万分感谢
解决方案
没太明白你说的意思,不知以下是不是你想要的。
--4在第一
select * from 表名 u where u.ReferralPath like '4%';
--4在第二
select * from 表名 u where u.ReferralPath like '%|4|%';
--4在第三
select * from 表名 u where u.ReferralPath like '%4';
解决方案二:
--使用substring('String',star,end) 截取字符串
--第一个
select * from table as A where left(A.ReferraPath, 1) = '4'
--还可以写为
select * from table as A where substring(A.ReferralPath ,1,1) = '4'
--第二个
select * from table as A where substring(A.ReferralPath ,3,3) = '4'
--第三个
select * from table as A where substring(A.ReferralPath ,5,5) = '4'
解决方案三:
我目前的解决方案是:
SELECT * FROM (
SELECT (len(ReferralPath)-len(replace(ReferralPath, '|', ''))) as Rs FROM vw_aspnet_Members where ( ('|'+ReferralPath+'|') like '%|1455 |%' OR ReferralPath=1455) as MyTwitter WHERE 1=1
在这里加条件判断:
一级: AND ReferralUserId=1455
二级: and ((Rs=1 AND (SELECT UnitInt FROM(select *,ROW_NUMBER() over(order by UnitInt) as row from dbo.F_SplitToInt(ReferralPath,'|'))A WHERE row=1)=1455) OR (Rs=2 AND (SELECT UnitInt FROM(select *,ROW_NUMBER() over(order by UnitInt) as row from dbo.F_SplitToInt(ReferralPath,'|'))A WHERE row=2)=1455))
三级: and Rs=2 AND (SELECT UnitInt FROM(select *,ROW_NUMBER() over(order by UnitInt) as row from dbo.F_SplitToInt(ReferralPath,'|'))A WHERE row=1)=1455
F_SplitToInt 这个为个函数方法用来分割ReferralPath ,返回个数据集 SQL写法如下:
CREATE FUNCTION [dbo].F_SplitToInt,
@spliter nvarchar(2)
)
RETURNS @returntable TABLE (UnitInt INT)
AS
BEGIN
WHILE(CHARINDEX(@spliter,@str)<>0)
BEGIN
INSERT INTO @returntable(UnitInt) SELECT CAST (SUBSTRING(@str,1,CHARINDEX(@spliter,@str)-1) AS INT)
SET @str = STUFF(@str,1,CHARINDEX(@spliter,@str),'')
END
INSERT INTO @returntable(UnitInt) SELECT CAST (@str AS INT)
RETURN
END
由于用了这个函数方法,导致整个SQL的性乱地下,求解决方法和思路,万分感谢
解决方案四:
select dbo.getIndex('2432|222|335','222','|') --结果为2
select dbo.getIndex('2432|222|335','2022','|') -- 结果为 -1
select dbo.getIndex('2432|222|335','2432','|') -- 结果为 1
select 1 where dbo.getIndex('2432|222|335','222','|') = 2 --- 单位置为2时输出 1
这样应该会用了吧
-- =============================================================================================
-- Author: swdenglian
-- Create date: 2015年12月2日 00:04:54
-- Description: 获取字符串(分隔符)位置,@str 原字符串,@strTarget 目标字符串,@char分隔符
-- =============================================================================================
create function getIndex(@str nvarchar(200),@strTarget nvarchar(200),@char nvarchar(10))
returns int
as
begin
declare @num int
declare @strSub varchar(200)
select @strSub = substring(@str,0,charindex(@strTarget,@str)) -- 截取字符串 例如:dbo.getIndex('2432|222|335','222','|') 截取结果为2432|
select @num = (LEN(@strSub) - LEN(REPLACE(@strSub,@char,''))) -- 计算位置
if(@num is NULL) --如果@strTarget 不在@str 中则将 @num 该为''
begin
select @num = replace(@num,NULL,'')
end
if(@num <> '') --判断如果num 不为'' 返回 字符串所在位置
return @num + 1
return -1 -- 否则返回-1,即表示目标字符串不在原字符串中
end
go
解决方案五:
-- =============================================================================================
-- Author: swdenglian
-- Create date: 2015年12月2日 00:04:54
-- Description: 获取字符串(分隔符)位置,@str 原字符串,@strTarget 目标字符串,@char分隔符
-- Modify[1]: <swdenglian,2015年12月4日 10:50:02,修改bug,当数据@strTarget不在@str中和在第一位置无区别修改
-- =============================================================================================
create function getIndex(@str nvarchar(200),@strTarget nvarchar(200),@char nvarchar(10))
returns int
as
begin
declare @num int
declare @strSub varchar(200)
if(charindex(@strTarget,@str) = 0)
return -1;
select @strSub = substring(@str,0,charindex(@strTarget,@str)) -- 截取字符串 例如:dbo.getIndex('2432|222|335','222','|') 截取结果为2432|
select @num = (LEN(@strSub) - LEN(REPLACE(@strSub,@char,''))) -- 计算位置
if(@num = 0)
begin
return 1;
end
return @num + 1
end
go
----使用方式为
select * from index_
select userid from index_ as a where dbo.getIndex(a.perPath,'4','|') = num
--num值
(-1:不在perPath中)
(1:第一位,2:第二位,3:第三位,以此类推)