我有一张像这样的表:
Id Word
--- ----
1 this
2 is
3 a
4 cat.
5 that
6 is
7 a
8 dog.
9 and
10 so
11 on
并且需要添加一个新的列,用于句号基于点字符:
Id Word S#
--- ---- --
1 this 1
2 is 1
3 a 1
4 cat. 1
5 that 2
6 is 2
7 a 2
8 dog. 2
9 and 3
10 so 3
11 on 3
效果方面的最佳解决方案是什么?
答案 0 :(得分:2)
select table.id, table.word, count(*) + 1 as serial_number
from table left join
( select id, word from table where word like '%.' ) Z
on table.id > Z.id
group by table.id, table.word
答案 1 :(得分:1)
你假设句子是由提升的身份号码形成的。这是一个非常糟糕的主意。
此查询应该为您提供有关句子中断的信息。 (将“T”替换为真实的表名。)
SELECT
Break1.Id as BreakId,
COALESCE(MAX(Break2.Id), 0) as PreviousBreakId,
COALESCE(COUNT(Break2.Id), 0) + 1 as BreakNumber
FROM
(SELECT Id FROM T WHERE Word LIKE '%.') as Break1,
(SELECT Id FROM T WHERE Word LIKE '%.') as Break2
WHERE Break2.Id < Break1.Id
GROUP BY Break1.Id
以下是您在UPDATE中使用它的方法。
UPDATE T
SET SentenceNum = (
SELECT B.BreakNumber
FROM
(
SELECT
Break1.Id as BreakId,
COALESCE(MAX(Break2.Id), 0) as PreviousBreakId,
COALESCE(COUNT(Break2.Id), 0) + 1 as BreakNumber
FROM
(SELECT Id FROM T WHERE Word LIKE '%.') as Break1,
(SELECT Id FROM T WHERE Word LIKE '%.') as Break2
WHERE
Break2.Id < Break1.Id
GROUP BY Break1.Id
) as B
WHERE T.Id >= B.PreviousBreak AND T.Id < B.BreakId
)
我提供了教育价值的查询,但我不能根据您的信息宽恕这种方法。
修改强>
我的原始版本第一句话有问题,因为基本上逻辑会查找不存在的前一个句子中断。 @ cravoori的解决方案通过左连接处理此问题。这是一个与我自己的答案相同精神的工作版本,它返回完整的单词列表而不是中断。除了交叉连接和虚拟零行之外,它的核心是相同的。
SELECT T.Id, MIN(T.Word) as Word, COUNT(Breaks.Id) as SentenceNumber
FROM T, (SELECT 0 as Id UNION ALL SELECT Id FROM T WHERE Word LIKE '%.') as Breaks
WHERE Breaks.Id < T.Id
GROUP BY T.Id;
答案 2 :(得分:0)
检查此查询以获得所需的输出:
DECLARE @Sentence TABLE(idn int identity,word varchar(50))
INSERT INTO @Sentence
VALUES('this'),('is'),('a'),('cat.'),('that'),('is'),('a'),('dog.'),('and'),('so'),('on.'),('I'),('love'),('india.')
--SELECT * FROM @Sentence
DECLARE @seq int=1
;WITH CTE(idn,word,seq) AS(
SELECT idn,word,CASE WHEN word not like '%.' then @seq END from @Sentence where idn=1
union all
SELECT s.idn,s.word,CASE WHEN s.word like '%.' then c.seq+1 else c.seq END from @Sentence s inner join CTE c on s.idn-1=c.idn
)
,CTE1(idn,word,seq) As
(SELECT idn,word,CASE WHEN word like '%.' then seq-1 else seq end as seq from CTE)
SELECT * FROM CTE1