4

基本的にプロセスを通じてアイテムを追跡する履歴テーブルが SQL Server にあります。アイテムには、プロセス全体で変更されない固定フィールドがいくつかありますが、プロセスのステップが増えるにつれて増加するステータスや Id などの他のいくつかのフィールドがあります。

基本的に、バッチ参照を指定して各アイテムの最後のステップを取得したいと考えています。だから私がするなら

Select * from HistoryTable where BatchRef = @BatchRef

バッチ内のすべてのアイテムのすべてのステップを返します-例

Id ステータス BatchRef ItemCount
1 1 Batch001 100
1 2 バッチ001 110
2 1 Batch001 60
2 2 バッチ001 100

しかし、私が本当に欲しいのは:

Id ステータス BatchRef ItemCount
1 2 バッチ001 110
2 2 バッチ001 100

編集: 謝罪 - TABLE タグを Markdown で動作させることができないようです - 手紙のヘルプに従い、プレビューで問題なく表示されます

4

6 に答える 6

10

テーブルにID列があると仮定します...

select 
    top 1 <fields> 
from 
    HistoryTable 
where 
    BatchRef = @BatchRef 
order by 
    <IdentityColumn> DESC
于 2008-08-27T10:15:55.543 に答える
7

テーブルのデザインを理解するのはちょっと難しいです - SO が区切り文字を食べたと思います。

これを処理する基本的な方法は、固定フィールドを GROUP BY し、いくつかの一意の値に対して MAX (または MIN) を選択することです (通常は日時が適切に機能します)。あなたの場合、GROUP BY は BatchRef と ItemCount になり、Id は一意の列になると思います

次に、テーブルに結合してすべての列を取得します。何かのようなもの:

SELECT * 
FROM HistoryTable
JOIN (
   SELECT 
       MAX(Id) as Id.
       BatchRef,
       ItemCount
   FROM HsitoryTable
   WHERE
       BacthRef = @batchRef
   GROUP BY
       BatchRef,
       ItemCount
 ) as Latest ON
   HistoryTable.Id = Latest.Id
于 2008-08-27T10:29:03.920 に答える
1
SELECT id, status, BatchRef, MAX(itemcount) AS maxItemcount 
FROM HistoryTable GROUP BY id, status, BatchRef 
HAVING status > 1 
于 2011-10-31T02:19:10.117 に答える
1

アイテム ID が段階的に番号付けされていると仮定します。

--Declare a temp table to hold the last step for each item id
DECLARE @LastStepForEach TABLE (
Id int,
Status int,
BatchRef char(10),
ItemCount int)

--Loop counter
DECLARE @count INT;
SET @count = 0;

--Loop through all of the items
WHILE (@count < (SELECT MAX(Id) FROM HistoryTable WHERE BatchRef = @BatchRef))
BEGIN
    SET @count = @count + 1;

    INSERT INTO @LastStepForEach (Id, Status, BatchRef, ItemCount)
        SELECT Id, Status, BatchRef, ItemCount
        FROM HistoryTable 
        WHERE BatchRef = @BatchRef
        AND Id = @count
        AND Status = 
        (
            SELECT MAX(Status) 
            FROM HistoryTable 
            WHERE BatchRef = @BatchRef 
            AND Id = @count
        )

END

SELECT * 
FROM @LastStepForEach
于 2008-08-31T08:52:31.640 に答える
0

WMD がフォーマットした方法でデータを解読するのは少し難しいですが、SQL 2005 の一般的なテーブル式を使用して、必要な種類のトリックを引き出すことができます。

with LastBatches as (
    select Batch, max(Id)
    from HistoryTable
    group by Batch
)
select *
from HistoryTable h
    join LastBatches b on b.Batch = h.Batch and b.Id = h.Id

またはサブクエリ(サブクエリでのグループ化が機能すると仮定します-頭のてっぺんから覚えていません):

select *
from HistoryTable h
    join (
        select Batch, max(Id)
        from HistoryTable
        group by Batch
    ) b on b.Batch = h.Batch and b.Id = h.Id

編集:バッチごとに最後のアイテムが必要だと思っていました。1 つのバッチだけが必要な場合は、他の回答 (上位 1 を実行し、降順に並べ替える) が適しています。

于 2008-08-27T10:19:08.203 に答える
0

すでに提案したように、実際に最初の行を取得するために、クエリを並べ替えて逆方向に並べ替えたいと思うでしょう。次に、おそらく次のようなものを使用したいと思うでしょう

SELECT TOP 1 ...

MSSQL 2k 以前、または SQL 準拠のバリアントを使用している場合

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,
    columns
  FROM tablename
) AS foo
WHERE rownumber = n

他のバージョン (または標準表記をサポートする他のデータベース システム) の場合、または

SELECT ... LIMIT 1 OFFSET 0

標準SQLサポートのない他のいくつかのバリアント。

行の選択に関する追加の議論については、この質問も参照してください。値の計算にテーブル スキャンが必要かどうかによって、集計関数 max() を使用する方が速い場合とそうでない場合があります。

于 2008-08-27T10:28:33.907 に答える