2

私はこのSQL文を使用していました:

SELECT "dateId", "userId", "Salary" 
FROM (
   SELECT *, 
          (row_number() OVER (ORDER BY "userId", "dateId"))%2 AS rn 
   FROM user_table
 ) sa 
 WHERE sa.rn=1 
   AND "userId" = 789 
   AND "Salary" > 0;

ただし、テーブルが新しい行を取得するたびに、クエリの結果は異なります。
何か不足していますか?

4

3 に答える 3

5

("dateId", "userId")それが一意であり、新しい行には常により大きな (後で) があると仮定しdateIdます。

いくつかのコメントの後:

あなたが必要だと思うもの:

SELECT "dateId", "userId", "Salary"
FROM (
   SELECT "dateId", "userId", "Salary"
         ,(row_number() OVER (PARTITION BY "userId"   -- either this
                              ORDER BY "dateId")) % 2 AS rn
   FROM   user_table
   WHERE  "userId" = 789                              -- ... or that
   ) sub
WHERE  sub.rn = 1
AND    "Salary" > 0;

に注意してPARTITION BYください。このようにして、各秒dateIdごとuserIdにスキップし、追加の (後の) 行はこれまでのところ選択を変更しません。

また、単一 userId( )の行を選択している限りWHERE "userId" = 789、述語をサブクエリに取り込み、同じ効果 (単一ユーザーの安定した選択) を実現します。両方は必要ありません。

WHEREサブクエリの句は、単一のユーザーに対してのみ機能し、 PARTITION BY1 つのクエリ内の任意の数のユーザーに対して機能します。

あれですか?それは...ですか?
彼らは私に「探偵」バッジを与えるべきです。
真剣に。

于 2011-09-23T14:36:20.003 に答える
0

いいえ、問題ないようです。新しい行があります。これらの行は、並べ替え後に古い行を別の位置に表示するように変更します。

于 2011-09-22T21:17:52.680 に答える
0

誰かが 789 未満の userId を持つ新しい行を挿入すると、順序が変更されます。たとえば、次の場合:

userId rn
 1      1
 4      0
 5      1
 6      0

userId = 2 の行を挿入すると、rn が変更されます。

userId rn
 1      1
 2      0
 4      1
 5      0
 6      1

N 行ごとに選択するには、シーケンスまたはタイムスタンプを含む列が必要です。

于 2011-09-22T21:25:09.053 に答える