2011-06-22 10 views
0

私はレースの結果を格納するテーブルを持っていると言います。毎日、いくつかの車がトラック周りをレースし、そのポジションを記録します。 (これは総単純化であるが、それは全体のポイントを取得します)ネストされたクエリはここで必要ですか?

表は次のようになります。

|Driver | Position | Date 
Andy  1   22/06/2011 
Paul  2   22/06/2011 
Cliff 3   22/06/2011 
Andy  2   21/06/2011 
Paul  1   21/06/2011 
Cliff 3   21/06/2011 

のように...

私は返すクエリを書きたいです特定の日付のドライバーポジションだけでなく、前日のポジションも表示します。私は、次の列を返すために、このために希望:

|Driver | Position | Date  | Position Yesterday 
Andy  1   22/06/2011 2 
Paul  2   22/06/2011 1 
Cliff 3   22/06/2011 3 

私はネストされたクエリを記述する必要があります推測が、私は本当にどこから始めれば分かりません。私はデータベースを複数回呼び出すことができ、アプリケーションで結果を構築できることを知っていますが、ベストプラクティスではないと思います。

+1

なぜあなたは日付を返すのですか?それは冗長です。 –

+0

はい、そうです。それは日付を返す必要はありません。 –

答えて

4
SELECT 
    [today].*, 
    [yesterday].Position 
FROM 
    yourTable AS [today] 
LEFT JOIN 
    yourTable AS [yesterday] 
    ON [today].Driver = [yesterday].Driver 
    AND [today].Date = [yesterday].Date + 1 
WHERE 
    [today].Date = '22/06/2011' 
+1

ちょうど頭が上がっています。OPがSQL Server 2008とデータ型 'DATE 'を使用すると、' Date + 1'は失敗します。 –

+0

私は多くのことを推測しました。ところで、あなたはすでに私の+1を持っています。 –

0

2番目のクエリの最初の結果UNION結果に対して1つのクエリを使用できます。それはそれを正しい方法で返す必要があります:* WHERE =

* FROM =

UNION

SELECT * FROM

SELECT *をあなたのニーズに*秒で入力します。

+0

彼は特別な列を追加しようとしていますが、余分な行はありません。 – MatBailie

+0

この場合、私の悪い、誤解されています。 – Manuel

0

これを行うには、前日を検索して結合します。

4

を見て、MS SQL Server 2008を使用している場合:

select 
    r1.driver, 
    r1.position, 
    r1.date 
    r2.position as prev_pos 
from 
    results r1 
left join 
    results r2 on r1.driver = r2.driver and r2.date = r1 - INTERVAL 1 DAY; 
2

ネスティングがため(より良い感謝@Demsを実行するようです彼のコメント) 日付をフィルタリングしてテーブルを自己結合する。

SELECT 
    today.driver, 
    today.position, 
    today.date, 
    yesterday.position 
FROM 
    your_table today, 
    (SELECT driver, position, (date - 1 day) "date" FROM your_table) yesterday 
WHERE 
    today.driver = yesterday.driver AND 
    today.date = yesterday.date 

:(ドライバ、日付)の組み合わせで使用すると、インデックス

SELECT t1.Driver,t1.Position, t1.Date, t2.Position 
FROM table t1 
LEFT JOIN (SELECT Driver, Position FROM table ON t1.Driver = t2.Driver AND t2.date ='21/06/2001') ON t1.Driver = t2.Driver 
WHERE t1.date = '22/06/2011' 
+0

LEFT JOINに 'AND t2.date = '21/06/2011''を置く必要があります。昨日のレコードがない場合、 't2.date'はNULLになり、WHERE句が失敗します。 – MatBailie

+0

修正済み!ありがとう!! – niktrs

+0

これは今はテストできませんが、 'DATEDIFF(DAY、a、b)= 1' SARGableですか?そして/または、これは 'a = DATEADD(DAY、-1、b)'とどのように比較されますか? – MatBailie

0

私はここが、ここでSQLクエリをテストすることはできませんが、適切なSQLに変換場合は動作するかもしれないいくつかの擬似SQL-コードですこれはもちろんコンパイルされません。私はwhere節について100%確信していません。あなたは、いくつかの左右の外側の結合をしなければならないかもしれません。また、最後のレースが昨日ではなく、前日であったときに問題が発生します。

これはとにかく役立ちます。

+1

これは確かにうまくいくことですが、これを行うには奇妙な方法です。 1つのことを除いて...あなたは今日を平等にするために昨日に追加する必要があります。あなたは昨日から1日を支配しています。つまり、明日の記録に加わることになります。 – MatBailie

+0

私は日付のことを考えていました - 1日は論理的な方法で、もちろんそれは最後にもう一方の方法で行わなければなりません。あなたが投稿した解決策を好むだろう。ちょうど私が鉱山を掲示したときに既に投稿された回答のリストにそれを持っていなかった –

0

ちょうど別のオプション:

@givendate = '22/06/2011' 

SELECT t1.Driver 
    , t1.Position 
    , t1.Date 
    , (SELECT t2.Position 
     FROM table t2 
     WHERE t2.Driver = t1.Driver 
      AND t2.date = DATEADD(day, @givendate, -1) 
     ) AS PositionYesterday 
FROM table t1 
WHERE t1.date = @givendate 
関連する問題