2012-03-29 1 views
2

データベースのメッセージのリストを格納しています(クラッシュした場合でも失わないようにします)。SQLクエリがColName = 1まで最上部の行を取得する

しかし、私がそれらを引き出すとき、私はそれらをチャンクと順序で引き出す必要があります。

CREATE TABLE MyMessages(MessageId bigint IDENTITY(1,1), 
    MyMessage varchar(100), IsWeirdMessage bit) 

INSERT INTO MyMessages(MyMessage, IsWeirdMessage) 
SELECT 'SomeValue1', 0 UNION ALL 
SELECT 'SomeValue2', 0 UNION ALL 
SELECT 'SomeValue3', 0 UNION ALL 
SELECT 'SomeValue3', 0 UNION ALL 
SELECT 'SomeValue4', 0 UNION ALL 
SELECT 'SomeValue5', 0 UNION ALL 
SELECT 'WeirdThingHere', 1 UNION ALL 
SELECT 'SomeValue7', 0 UNION ALL 
SELECT 'SomeValue8', 0 UNION ALL 
SELECT 'SomeValue9', 0 UNION ALL 
SELECT 'OtherWeirdStuff', 1 UNION ALL 
SELECT 'SomeValue11', 0 
GO 

方法:

は、私は何を探しています、私はこのようになりますテーブルを持っていると仮定すると、IsWeirdMessage = 1

だから、コラムまで、私の一番上のx行を与えるクエリですSomeValue1SomeValue5(順番に)、IsWeirdMessageのキー入力をオフにすることができますか?それを行う必要があり、このような

答えて

4

何か:

@MessageIDはあなたが取得した最後の奇妙なメッセージの値をある
select * from MyMessages 
where messageid > @MessageID 
and messageid <= 
    (select min(messageid) from MyMessages 
    where IsWeirdMessage = 1 and messageid > @MessageID) 
order by messageid 

。 @PartIDは、あなたがしたいことをパーティションの識別子であるhttp://www.sqlfiddle.com/#!3/10336/9

+1

答えをありがとう! SQLFiddleを教えてくれてありがとう。それはとても素晴らしいです! – Vaccano

1
SELECT m.MessageID, m.MyMessage 
FROM dbo.MyMessages AS m 
WHERE NOT EXISTS 
(
    SELECT 1 FROM dbo.MyMessages AS m2 
    WHERE IsWeirdMessage = 1 
    AND m2.MessageID < m.MessageID 
) 
ORDER BY MessageID; 
+0

答えをありがとう!私は実際のテーブルでインデックスシークを行うことになったので、私はMellamokbのソリューションに行った。あなたのソリューションは素晴らしかったですが、インデックススキャンを行っていました。 – Vaccano

+0

公平であるために、あなたは私たちにあなたのインデックス構造を教えてくれませんでした。クエリが異なる動作をしたか、スキャンを見て、それが悪化していると仮定しましたか?多くの場合、範囲シークは、インデックスシークのように見えるものの後ろに隠れています。 –

+0

真実、私はしませんでした。 (私はそれが問題ではないと思った)両方の答えは非常に良い(そして本当にうまくいった)。私は何かを見つけなければなりませんでしたが(しかし、非常に小さい)、インデックスシークの背後にあるレンジスキャンについては...それは私を緊張させます。私はこれまで聞いたことがありません。しかし、このケースでは、両方の実際のパフォーマンス(実行時間)は十分に近いものでした。 – Vaccano

0
select b.* 
from 
    ( select 
      row_number() over (order by (select 1)) as PartitionId 
      ,isnull((select max(t.MessageId) from MyMessages t where t.MessageId < tb.MessageId and t.IsWeirdMessage = 1), 0) as StartID 
      ,tb.MessageId as EndId 
     from MyMessages tb 
     where IsWeirdMessage = 1 
     union all 
     select count(case when IsWeirdMessage = 1 then MessageId else null end) + 1 
      ,max(case when IsWeirdMessage = 1 then MessageId else 0 end) 
      ,max(messageId) + 1 
     from MyMessages 
    ) as a 
    cross apply 
    ( select * from MyMessages b 
     where 
      b.MessageId > a.StartID 
      and b.MessageId < a.EndID 
    ) as b 
where a.PartitionId = @PartID 

:あなたは

デモなど、第二のバッチを取得するには7、その後、最初のバッチを取得するには0で始まります選択してください

関連する問題