1

次のフィールドを持つテーブルを用意します。

順序、グループ、シーケンス

特定のグループ内のすべての注文が連続したシーケンスを形成する必要があります。例:1、2、3、4または4、5、6、7。単一のSQLクエリを使用して、このルールに準拠していない注文を確認するにはどうすればよいですか?ありがとうございました。

Example data:

Order   Group   Sequence
1   1   3
2   1   4
3   1   5
4   1   6
5   2   3
6   2   4
7   2   6

Expected result:
Order
5
6
7

クエリが間違ったシーケンスを持つグループのみを返す場合にも受け入れられます。サンプルデータの場合は2です。

4

6 に答える 6

4

シーケンスが生成され、したがって複製できないと仮定します。


SELECT group
 FROM theTable
 GROUP BY group
 HAVING MAX(Sequence) - MIN(Sequence) <> (COUNT(*) - 1);

于 2009-05-18T09:29:40.923 に答える
2

これはどう?

count(Sequence)<= max(Sequence)-min(Sequence)を持つ
グループごとにテーブルグループからグループを選択します

[編集]これは、Sequenceが特定のグループ内での重複を許可しないことを前提としています。使用する方が良い場合があります:
count!= max --min + 1

[もう一度編集]D'oh、まだ完璧ではありません。ただし、重複をフラッシュする別のクエリで処理されます。

[最後の編集]元のクエリはsqliteで正常に機能しました。これは、簡単なテストで利用できたものです。SQLサーバーよりもはるかに寛容です。ポインタをくれたBellに感謝します。

于 2009-05-18T09:22:45.507 に答える
2

個人的には、要件を再考することを検討したいと思います。レコードがロールバックされるためにシーケンスのギャップが発生しやすいのは、リレーショナルデータベースの性質です。たとえば、注文で4つのアイテムが作成され始めたが、1つが何らかの理由で失敗し、ロールバックされたとします。シーケンスを手動で事前計算した場合、ロールバックされたものが最後のものではないというギャップが生じます。他のシナリオでは、複数のユーザーがほぼ同時にシーケンス値を検索したり、直前に顧客が注文から1つのレコードを削除したりすると、ギャップが生じる可能性があります。親子関係からは得られない連続したシーケンスを持つことから、正直に何を得ようとしていますか?

于 2009-05-18T17:53:04.603 に答える
1

このSQLは、連続シーケンスがない次数3と4を選択します。

DECLARE @Orders TABLE ([Order] INTEGER, [Group] INTEGER, Sequence INTEGER)

INSERT INTO @Orders VALUES (1, 1, 0)
INSERT INTO @Orders VALUES (1, 2, 0)
INSERT INTO @Orders VALUES (1, 3, 0)

INSERT INTO @Orders VALUES (2, 4, 0)
INSERT INTO @Orders VALUES (2, 5, 0)
INSERT INTO @Orders VALUES (2, 6, 0)

INSERT INTO @Orders VALUES (3, 4, 0)
INSERT INTO @Orders VALUES (3, 6, 0)

INSERT INTO @Orders VALUES (4, 1, 0)
INSERT INTO @Orders VALUES (4, 2, 0)
INSERT INTO @Orders VALUES (4, 8, 0)

SELECT o1.[Order]
FROM @Orders o1
     LEFT OUTER JOIN @Orders o2 ON o2.[Order] = o1.[Order] AND o2.[Group] = o1.[Group] + 1
WHERE o2.[Order] IS NULL
GROUP BY o1.[Order]
HAVING COUNT(*) > 1
于 2009-05-18T09:28:31.033 に答える
0

つまり、テーブルは次の形式になります。

Order Group Sequence
1     1     4
1     1     5
1     1     7

..そして、1,1,6が欠落していることを知りたいですか?

select
  min(Sequence) MinSequence, 
  max(Seqence) MaxSequence 
from 
  Orders 
group by 
  [Order], 
  [Group]

特定の注文とグループの範囲を見つけることができます。

これで、シーケンスに使用できるすべての数値が含まれている特殊な数値テーブルを使用して、正しいデータをシミュレートできます。これがそのような数値表の良い例ですどのように作成するかは重要ではありません。xからyまでのすべての数値を含むExcelファイルを作成し、そのExcelシートをインポートすることもできます。

私の例では、1つの列「n」のみを持つ「Numbers」と呼ばれるそのような数値テーブルを想定しています。

select 
  [Order], 
  [Group], 
  n Sequence
from
  (select min(Sequence) MinSequence, max(Seqence) MaxSequence from [Table] group by [Order], [Group]) MinMaxSequence
  left join Numbers on n >= MinSequence and n <= MaxSequence

そのSQLを新しいビューに配置します。私の例では、ビューを「vwCorrectOrders」と呼びます。

これにより、シーケンスが連続しているデータが得られます。これで、そのデータを元のデータと結合して、欠落しているシーケンスを見つけることができます。

select 
  correctOrders.*
from
  vwCorrectOrders co 
  left join Orders o on 
      co.[Order] = o.[Order] 
  and co.[Group] = o.[Group]
  and co.Sequence = o.Sequence
where
  o.Sequence is null

あなたに与えるべき

Order Group Sequence
1     1     6
于 2009-05-18T10:03:23.290 に答える
0

しばらくして、私は次の解決策を思いつきました。動作しているように見えますが、非常に非効率的です。改善の提案を追加してください。

SELECT OrdMain.Order
  FROM ((Orders AS OrdMain
  LEFT OUTER JOIN Orders AS OrdPrev ON (OrdPrev.Group = OrdMain.Group) AND (OrdPrev.Sequence = OrdMain.Sequence - 1))
  LEFT OUTER JOIN Orders AS OrdNext ON (OrdNext.Group = OrdMain.Group) AND (OrdNext.Sequence = OrdMain.Sequence + 1))
WHERE ((OrdMain.Sequence < (SELECT MAX(Sequence) FROM Orders OrdMax WHERE (OrdMax.Group = OrdMain.Group))) AND (OrdNext.Order IS NULL)) OR
      ((OrdMain.Sequence > (SELECT MIN(Sequence) FROM Orders OrdMin WHERE (OrdMin.Group = OrdMain.Group))) AND (OrdPrev.Order IS NULL))
于 2009-05-18T10:44:08.947 に答える