假设我在 SQL 中有一个由多行信息组成的字段,每行信息由 i 个主题组成,每个主题由 m 个信息点组成。主题以“我”开头。和带有破折号的信息。它看起来像:
________________________________________________
|Number | Information
|===============================================
|1 | 1. Topic 1.1
| | -Info 1.1.1
| | - ... [more info]
| | 2. Topic 1.2
| | -Info 1.2.1
| | - ...[more info]
| | ... [more topics]
|_______|_____________________________
|2 | 1. Topic 2.1
|....and so on
我对这些信息所做的是将每个主题解析到它自己的列中,然后取消透视这些列并搜索包含给定关键字@keyword 的主题。
目前的代码是这样的:
Select
Number
,Case When Information LIKE '%1. %2. %'
Then substring (Information, charindex('1.',Information),
charindex('2.', Information) -(charindex('1.',Information)+2) )
Else Information
End as [Topic1]
,Case When Information LIKE '%2. %3. %'
Then substring (Information, charindex('2.',Information),
charindex('3.', Information) -(charindex('2.',Information)+2) )
Else 'N/A'
End as [Topic2]
...repeat 2nd case for each set of numbers up to '%20. %21. %'
第一个不同的唯一原因是,如果它与模式不匹配,那么我想捕获整个领域,这样我就不会错过任何东西。然后,我unpivot
将我刚刚创建的主题字段放入通用[Topic]
字段,然后使用WHERE [Topic] LIKE '%' +@keyword+ '%'
提取任何特定主题及其相关案例编号以作为我的最终表格输出。这些案例可以附加 1 到 40 多个主题,每个主题附加 1-7 个信息字段。
注意:为了使代码更易于阅读,我不会以正确的语法编写我的子字符串代码,而是选择编写 substring(Information,ci(@Iter), ci (@Iter+1)-ci(@Iter))
表示从'(iter).'给出的位置开始运行的子串。到“(iter+1)”给出的位置。
我想做的是执行以下操作:
Declare @Iter smallint
Declare @Result varchar(max)
Select
Number
, Set @Iter=1
Set @Result = ' '
Case When Information LIKE '%'+@keyword+'%' --keyword chosen at front end
Then While @Iter < @n --@n set by the user from front end
Begin
Case When Information LIKE '%' + cast(@Iter as varchar(5))
+ '. %'+cast((@Iter+1) as varchar(5))+'. %'
and substring(Information,ci(@Iter), ci(@Iter+1)-ci(@Iter) )
LIKE '%'+@keyword+'%'
Then Set @Result = @Result +substring(Information,ci(@Iter),
ci(@Iter+1)-ci(@Iter) )
Else Set @Result = @Result end
Set @Iter = @Iter +1
End
Else ' ' end [Result]
如果我想要的东西不清楚,我会介绍我想要完成的东西
I want to output a list of case numbers that include Topics that include the keyword. For each case in the list I want to output only those topics that include the keyword. I want to allow the end user of the report to choose how many Topics in each case they'll search. I don't want to have to create a table with a column for each Topic when I can't know how many the user will want to create.
出于这些考虑,循环似乎是最好的选择,但在尝试实现这一点时存在问题。
- SQL server won't allow me to utilize a loop in my Select statement--
Incorrect syntax near 'While'
.- The place where the information comes from prohibits normalization of the information in the table I'm searching
- Even if it didn't I am barred from creating my own permanent tables at work, so I can't normalize the data for all incoming data
- I am also not allowed to write my own stored procedures.
如果有任何方式(例如通过 cte)来实现这些更改,我愿意听取他们的意见!我主要是在寻找使代码看起来不那么令人生畏的方法(在我当前的 cte 中生成 20 个字段的 20 个案例看起来很可怕,然后需要 3 个 ctes 才能正确解包 [unpivot,删除满足特定条件的某些案例,组合成一个可行的输出表])
提前感谢您阅读本文并提供帮助!
最佳答案
我觉得你工作太辛苦了。 如果您只需要主题名称和数字,那么用换行符拆分信息列不是更容易,然后收集所有以数字而不是“破折号”开头的行,那么您将得到一个字符串列表看起来像:
然后只需将行与关键字匹配就很容易了?
像这样未经测试的 SQL:
select SUBSTRING(s.value,1, PATINDEX('% %', s.Value) - 1) AS topicId
, SUBSTRING(s.Value, PATINDEX('% %', s.Value), LENGTH(s.Value)) AS topicText
from [table that would make Codd cry] t
cross apply STRING_SPLIT(t.Information, CHAR(13)) s
where s.Value LIKE '[0-9]%' -- Starts with a number
AND s.Value LIKE @keywords --matches keywords
不确定您是否可以创建函数或者您的 SQL Server 版本中是否有 STRING_SPLIT 可用,但如果您不这样做,您可以在网上找到一些字符串拆分 CTE 来为您完成这项工作
关于sql-server - 在 SQL Server 2012 的情况下,尝试在我的 select 语句中运行 while 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34140927/