我有一个名为Event的字段,它包含如下数据:
查看:
ID Event
1 2015-T4-C
2 2015-G4-C
3 2015-T4-C; 2015-R4-C; 2015-Z4-C
4 2018-T4-C
5 2015-T4-Z
使用SQL SELECT(MSSQL)如何使用通配符替换字符串的通配符部分?
e.g。这是我想要做的虽然不起作用。替换的第一次出现是为了满足只有一个实例的值,第二次替换它以满足具有多个实例的值'; '在他们中:
SELECT
REPLACE(REPLACE(view.Event, '_____T___', ''), '_____T___; ', '')
FROM view
我要找的结果是:
查看结果
ID Event
1
2 2015-G4-C
3 2015-R4-C; 2015-Z4-C
4
5
谢谢
编辑:有多个'T'的实例,例如2017-T4-C,2018-T4-C,2019-T4-C,2015-T4-Z所以不能在'2015-T4-C'上使用替换
编辑2:
P.S。它就像这样开始
原始表
ID Event
1 2015-T4-C
2 2015-G4-C
3 2015-T4-C
3 2015-R4-C
3 2015-Z4-C
etc
然后我使用一个XML查询来将它们放在同一行上,例如。
3 2015-T4-C; 2015-R4-C; 2015-Z4-C
编辑3 - 现在我知道在SELECT中不可能使用通配符替换它会改变问题。我要找的结果是:
ID EventFilter1 EventFilter2
1 2015-T4-C
2 2015-G4-C
3 2015-R4-C; 2015-Z4-C 2015-T4-C
4 2018-T4-C
5 2015-T4-Z
我可以回去以不同的方式从原始表中提取数据:
原始表
ID Event
1 2015-T4-C
2 2015-G4-C
3 2015-T4-C
3 2015-R4-C
3 2015-Z4-C
etc
编辑4:这是一个新的问题,知道不可能使用通配符:
您好
我有一个客户表,我有一个事件表。每个客户有多个事件。我需要导出到分号分隔的单行以进行外部系统导入,根据过滤器将结果拆分为两列。
活动表:
ID Event
1 2015-T4-C
2 2015-G4-C
3 2015-T4-C
3 2015-R4-C
3 2015-Z4-C
4 2018-T4-C
4 2018-T4-W
4 2018-K4-I
4 2018-Z4-W
5 2015-T4-Z
期望的结果:
ID EventFilter1(T) EventFilter2(notT)
1 2015-T4-C
2 2015-G4-C
3 2015-T4-C 2015-R4-C; 2015-Z4-C
4 2018-T4-C; 2018-T4-W 2018-K4-I; 2018-Z4-W
5 2015-T4-Z
目前我使用两个单独的连接但是只想使用一个简单并加速它。这是我现在所做的,我该如何简化呢?目标1是让它更快,目标2是让它更简单但更乐于支持速度而不是简单。
SELECT c.ID, e.EventFilter1(T), e2.EventFilter2(notT)
FROM Customers c
LEFT JOIN (SELECT
c.ID,
EventFilter1(T) = STUFF((
SELECT distinct '; ' + e.Event
FROM Events e
WHERE c.ID = e.ID AND Event like '%-T%'
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM Customers c WHERE c.ID in (SELECT ID FROM Events)) as e
on c.ID = e.ID
LEFT JOIN (SELECT
c.ID,
EventFilter2(notT) = STUFF((
SELECT distinct '; ' + e2.Event
FROM Events e2
WHERE c.ID = e2.ID AND Event not like '%-T%'
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM Customers c WHERE c.ID in (SELECT ID FROM Events)) as e2
on c.ID = e2.ID
那么有没有一种方法可以在连接子查询中提取没有过滤器的所有数据,然后在主查询中过滤并拆分它,或者我可以在一个子查询中拉出两组带有两个过滤器的数据? e.g:
LEFT JOIN (SELECT
c.ID,
EventFilter1(T) = STUFF((
SELECT distinct '; ' + e.Event
FROM Events e
WHERE c.ID = e.ID AND Event like '%-T%'
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
EventFilter2(notT) = STUFF(( **** What do I put here? ****
FROM Customers c WHERE c.ID in (SELECT ID FROM Events)) as e
on c.ID = e.ID
答案 0 :(得分:1)
借助CROSS APPLY和一点点XML作为拆分器
示例强>
Declare @YourTable table (ID int, [Event] varchar(500))
Insert Into @YourTable values
(1, '2015-T4-C'),
(2, '2015-G4-C'),
(3, '2015-T4-C; 2015-R4-C; 2015-Z4-C'),
(4, '2018-T4-C'),
(5, '2015-T4-Z')
Declare @Pattern varchar(100) = '_____T___'
Select A.ID
,NewVal =IsNull(B.S,'')
From @YourTable A
Cross Apply (
Select S = Stuff((Select '; ' +RetVal
From (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(A.[Event],';','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) B1
Where PatIndex(@Pattern,RetVal)=0
Order by RetSeq
For XML Path ('')),1,2,'')
) B
<强>返回强>
ID NewVal
1
2 2015-G4-C
3 2015-R4-C; 2015-Z4-C
4
5
答案 1 :(得分:0)
我认为原来的问题不完整...... 我们看到的数据是xml上的内容的结果,因此应该首先清理原始表以获得正确的结果。
请在下面找到针对tbevents的解决方案作为原始事件表。
create table #tbpattern(
myPat varchar(10)
)
insert into #tbpattern
values ('T1'),('T2'),('T3'),('T4-C'),('T4-Z')
select * from #tbpattern
create table #tbevents
(
eventid varchar(1000)
)
insert into #tbevents
values ('2015-T4-C'),('2015-G4-C'),('2015-Z4-C'),('2018-T4-C'),('2015-T4-Z')
select e.eventid
from #tbevents e
where not exists
(
select 1 from #tbpattern p where charindex(p.myPat,e.eventid) > 0
)
drop table #tbpattern
drop table #tbevents
从上面的结果中应用STUFF
答案 2 :(得分:0)
你有固定长度的字符串。这确实为您提供了一些选择。这是一个相当痛苦的问题:
select (case when substr(t.event, 6, 1) = 'T'
then stuff(t.event, 1, 11, '')
when substr(t.event, 17, 1) = 'T'
then stuff(t.event, 12, 11, '')
when substr(t.event, 28, 1) = 'T'
then stuff(t.event, 23, 11, '')
. . .
end)
这确实有一个缺点,即只删除一个。
答案 3 :(得分:0)
我添加了另一个答案,因为EDITS偏离了原来的问题
Declare @YourTable table (ID int, [Event] varchar(50))
Insert Into @YourTable values
(1 ,'2015-T4-C'),
(2 ,'2015-G4-C'),
(3 ,'2015-T4-C'),
(3 ,'2015-R4-C'),
(3 ,'2015-Z4-C'),
(4 ,'2018-T4-C'),
(4 ,'2018-T4-W'),
(4 ,'2018-K4-I'),
(4 ,'2018-Z4-W'),
(5 ,'2015-T4-Z')
Declare @Pattern varchar(100) = '_____T___'
Select A.ID
,NewCol1 = IsNull(B.S,'')
,NewCol2 = IsNull(C.S,'')
From (Select Distinct ID from @YourTable) A
Cross Apply (
Select S = Stuff((Select Distinct '; ' +[Event]
From @YourTable
Where PatIndex(@Pattern,[Event])=0
and ID = A.ID
For XML Path ('')),1,2,'')
) B
Cross Apply (
Select S = Stuff((Select Distinct '; ' +[Event]
From @YourTable
Where PatIndex(@Pattern,[Event])>0
and ID = A.ID
For XML Path ('')),1,2,'')
) C
<强>返回强>
ID NewCol1 NewCol2
1 2015-T4-C
2 2015-G4-C
3 2015-R4-C; 2015-Z4-C 2015-T4-C
4 2018-K4-I; 2018-Z4-W 2018-T4-C; 2018-T4-W
5 2015-T4-Z