0

これはsybase 15です。これが私の問題です。

私は2つのテーブルを持っています。

t1.jobid          t1.date
------------------------------
1                   1/1/2012
2                   4/1/2012
3                   2/1/2012
4                   3/1/2012

t2.jobid   t2.userid    t2.status
-----------------------------------------------
1              100            1
1              110            1
1              120            2
1              130            1
2              100            1
2              130            2
3              100            1
3              110            1
3              120            1
3              130            1
4              110            2
4              120            2

最近の 2 つの仕事のステータスが 2 の人をすべて検索したいと考えています。

私の計画は、t1 と t2 を結合し、特定のユーザーの日付順に逆順に並べられた派生テーブルの上位 2 つを取得することでした。したがって、上位 2 つは特定のユーザーの最新のものになります。

そうすれば、個人の最新の仕事番号がわかります。誰もがすべての仕事に就いているわけではありません。

次に、sum(status) = 4 などのステータス 2 を検索する派生テーブルに対して結合する外部クエリを作成するつもりでした。これにより、ステータス 2 が 2 つある人が検索されます。

しかし、sybase では、派生テーブルで order by 句を使用できません。

これをどうするかについての提案はありますか?

すべてのユーザーをループする小さなプログラムをいつでも作成できますが、それから 1 つの horrendus sql を作成しようとしました。

ジューシーなものですね。

4

2 に答える 2

1
With Table1 As
    (
    Select 1 As jobid, '1/1/2012' As [date]
    Union All Select 2, '4/1/2012'
    Union All Select 3, '2/1/2012'
    Union All Select 4, '3/1/2012'
    )
    , Table2 As
    (
    Select 1 jobid, 100 As userid, 1 as status
    Union All Select 1,110,1
    Union All Select 1,120,2
    Union All Select 1,130,1
    Union All Select 2,100,1
    Union All Select 2,130,2
    Union All Select 3,100,1
    Union All Select 3,110,1
    Union All Select 3,120,1
    Union All Select 3,130,1
    Union All Select 4,110,2
    Union All Select 4,120,2
    )
    , MostRecentJobs As
    (
    Select T1.jobid, T1.date, T2.userid, T2.status
        , Row_Number() Over ( Partition By T2.userid Order By T1.date Desc ) As JobCnt
    From Table1 As T1
        Join Table2 As T2
            On T2.jobid = T1.jobid
    )
Select *
From MostRecentJobs As M2
Where Not Exists    (
                    Select 1
                    From MostRecentJobs As M1
                    Where M1.userid = M2.userid
                        And M1.JobCnt <= 2
                        And M1.status <> 2
                    )
     And M2.JobCnt <= 2

ここでは、Sybase 15 に存在する多くの機能を使用しています。まず、サンプル データとクエリのクランプの両方に共通テーブル式を使用しています。次に、ランキング機能Row_Numberを使用してジョブを日付順に並べています。

あなたが提供したサンプルデータでは、最新の2つのジョブの両方がステータス「2」であるという要件を満たしているユーザーはいないことに注意してください。

__

編集

ランキング機能をサポートしていない Sybase のバージョン (15.2 より前の Sybase 15 など) を使用している場合は、Counts を使用してランキング機能をシミュレートする必要があります。

Create Table #JobRnks
    (
    jobid int not null
    , userid int not null
    , status int not null
    , [date] datetime not null
    , JobCnt int not null
    , Primary Key ( jobid, userid, [date] )
    )

Insert #JobRnks( jobid, userid, status, [date], JobCnt )    
Select T1.jobid, T1.userid, T1.status, T1.[date], Count(T2.jobid)+ 1 As JobCnt
From    (
        Select T1.jobid, T2.userid, T2.status, T1.[date]
        From @Table2 As T2
            Join @Table1 As T1
                On T1.jobid = T2.jobid
        ) As T1
    Left Join   (
                Select T1.jobid, T2.userid, T2.status, T1.[date]
                From @Table2 As T2
                    Join @Table1 As T1
                        On T1.jobid = T2.jobid
                ) As T2
        On T2.userid = T1.userid
            And T2.[date] < T1.[date]
Group By T1.jobid, T1.userid, T1.status, T1.[date]

Select *
From #JobRnks As J1
Where Not Exists    (
                    Select 1
                    From #JobRnks As J2
                    Where J2.userid = J1.userid
                        And J2.JobCnt <= 2
                        And J2.status <> 2
                    )
    And J1.JobCnt <= 2

ここで一時テーブルを使用する理由は、パフォーマンスと読みやすさのためです。技術的には、派生テーブルとして使用される 2 つの場所に一時テーブルのクエリをプラグインし、同じ結果を得ることができます。

于 2012-04-27T16:16:28.047 に答える
1

ウィンドウ関数を使用して列を追加することで、サブクエリの行をランク付けできます。次に、グループ内で適切なランクを持つ行を選択します。

私は Sybase を使用したことがありませんが、ドキュメントにはこれが可能であることが示されているようです。

于 2012-04-27T15:20:09.737 に答える