0

私は次のようなテーブルを持っています:

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

パフォーマンスの観点から最適なソリューションは何ですか?

4

3 に答える 3

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
于 2012-07-08T17:36:55.693 に答える
1

あなたは文がID番号の昇順で形成されていると仮定しています。それは本当に悪い考えです。

このクエリは、文の区切りに関する情報を提供するはずです。(「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;
于 2012-07-08T17:56:09.917 に答える
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
于 2012-07-09T09:55:05.227 に答える