1

このようなサンプルデータがあります

ID     DATE           TIME     STATUS 
---------------------------------------------
A      01-01-2000     0900     ACTIVE 
A      05-02-2000     1000     INACTIVE 
A      01-07-2000     1300     ACTIVE 
B      01-05-2005     1000     ACTIVE 
B      01-08-2007     1050     ACTIVE
C      01-01-2010     0900     ACTIVE 
C      01-07-2010     1900     INACTIVE

上記のデータセットから、最初はアクティブで、その後 に非アクティブになり、その後 まで非アクティブであったことにID='A'注目すると、 .A05-02-200001-07-2000

つまり、Aは から まで非アクティブでし05-Feb-200001-July-2000

私の質問は次のとおりです。

  1. それを使ってクエリを実行すると、(ID=A, Date=01-04-2000)私に与えるはずです

    A      05-02-2000     1000     INACTIVE 
    

    その日付はそのデータセットで利用できないため、前の日付を検索して出力する必要があるためです。

  2. また、私の条件であれば、(ID=A, Date=01-07-2000)テーブルに存在する値を出力するだけでなく、以前の値も出力する必要があります

    A      05-02-2000     1000     INACTIVE 
    A      01-07-2000     1300     ACTIVE 
    

このクエリを解決するのを手伝ってくれる人がいれば、本当に感謝しています。これを解決するために最善を尽くしています。

みんなありがとう。

これについて何か考えていますか?

アファク

4

2 に答える 2

1

次のようなものが機能するはずです。

SELECT ID, Date, Time, Status
 from (select ID, Date, Time, Status, row_number() over (order by Date) Ranking
        from MyTable
        where ID = @SearchId
         and Date <= @SearchDate) xx
 where Ranking < 3
 order by Date, Time

これにより、最大で 2 行が返されます。日付と時刻のデータ型の列を使用しているかどうか、または実際に予約語を列名として使用しているかどうかは明確ではないため、それについては大騒ぎする必要があります。(時間は省きましたが、さまざまな順序付けとフィルタリングに簡単に追加できます。)


行を含めるか除外するかは、別の行で返される値に依存するため、修正された基準を考えると、少し複雑になります。ここで、「2 行目」の行は、2 行以上ある場合、「1 行目」の行が特定の値に等しい場合にのみ含まれます。これを行う標準的な方法は、データをクエリして最大値を取得し、最初のセットの結果を参照しながら再度クエリを実行することです。

ただし、row_number を使用すると、多くの厄介なことを行うことができます。これに取り組みます:

SELECT ID, Date, Time, Status
 from (select
          ID, Date, Time, Status
         ,row_number() over (partition by case when Date = @SearchDate then 0 else 1 end
                             order by     case when Date = @SearchDate then 0 else 1 end
                                         ,Date) Ranking
        from MyTable
        where ID = @SearchId
         and Date <= @SearchDate) xx
 where Ranking = 1
 order by Date, Time

これは日付に対してのみ機能するため、日付/時刻の問題を解決する必要があります。

于 2012-05-24T14:22:05.717 に答える
0

基本的に、指定された日付が次の場合、行をプルする必要があります。

1) 最後のレコード、または

2) 最後の非アクティブなレコード。

また、2 つの条件は、同じ行だけでなく、2 つの異なる行にも一致する場合があります。

このロジックを SQL Server 2005+ に実装する方法は次のとおりです。

WITH ranked AS (
  SELECT
    ID,
    Date,
    Time,
    Status,
    RankOverall  = ROW_NUMBER() OVER (                    ORDER BY Date DESC),
    RankByStatus = ROW_NUMBER() OVER (PARTITION BY Status ORDER BY Date DESC)
  FROM Activity
  WHERE ID = @ID
    AND Date <= @Date
)
SELECT
  ID,
  Date,
  Time,
  Status,
FROM ranked
WHERE RankOverall = 1
   OR Status = 'INACTIVE' AND RankByStatus = 1
于 2012-05-25T06:21:14.627 に答える