T-SQL

2011-06-25 4 views
1

の最後の取引(当日または前日)からの1日の終わりの利益の合計を見つけましたa question in April@Mikaelが私にそれを解決するのを助けてくれました。それ以来、要件が変更されており、クエリの作成方法を把握することができません。 テーブル構造がT-SQL

 
SID Sdate     Profit Units 
1 7/26/2010 9:15:00 AM -37.5 -1  
1 7/26/2010 12:00:00 PM -125 -1  
1 7/26/2010 12:45:01 PM -12.5 -1  
1 7/26/2010 12:45:02 PM 0  0  
1 7/26/2010 12:45:03 PM -75  1  
1 7/26/2010 2:00:01 PM -12.5 1  
1 7/26/2010 2:00:02 PM 0  0  
1 7/26/2010 2:00:03 PM -125 -1  
1 7/26/2010 2:15:00 PM -50  -1 
1 7/27/2010 9:15:00 AM 25  -1  
1 7/27/2010 12:00:00 PM 196  -1  
1 7/27/2010 2:15:00 PM -12.5 -1 
1 7/28/2010 9:15:00 AM 425  -1  
1 7/28/2010 12:00:00 PM -125 -1  
1 7/28/2010 2:15:00 PM -12.5 -1 
1 7/29/2010 9:15:00 AM -37.5 -1  
1 7/29/2010 12:00:00 PM -90  -1  
1 7/29/2010 12:45:01 PM -12.5 -1  
1 7/29/2010 12:45:02 PM 0  0  
1 7/29/2010 12:45:03 PM -75  1  
1 7/29/2010 2:15:00 PM 23  1 

計算は次のように説明されている。結果は純利益の列の合計は、のために毎日の14:15で取られ

 
SID Sdate  Profit Units 
1 7/26/2010 -175 -1 
1 7/27/2010 33.5 -1 
1 7/28/2010 321  -1 
1 7/29/2010 -52  1 

だろう

 
SID Sdate     Profit Units End-of-day-Profit Comments 
1 7/26/2010 9:15:00 AM -37.5 -1  
1 7/26/2010 12:00:00 PM -125 -1  
1 7/26/2010 12:45:01 PM -12.5 -1  
1 7/26/2010 12:45:02 PM 0  0  
1 7/26/2010 12:45:03 PM -75  1  
1 7/26/2010 2:00:01 PM -12.5 1  
1 7/26/2010 2:00:02 PM 0  0  
1 7/26/2010 2:00:03 PM -125 -1  
1 7/26/2010 2:15:00 PM -50  -1 -175 SUM of profit(row 9 to row 11) going back to 7/26/2010 2:00:02 PM 
1 7/27/2010 9:15:00 AM 25  -1  
1 7/27/2010 12:00:00 PM 196  -1  
1 7/27/2010 2:15:00 PM -12.5 -1 33.5 SUM of profit (row 9 to row 14) going back to 7/26/2010 2:00:02 PM 
1 7/28/2010 9:15:00 AM 425  -1  
1 7/28/2010 12:00:00 PM -125 -1  
1 7/28/2010 2:15:00 PM -12.5 -1 321  SUM of profit(row9 to row 17) going back to 7/26/2010 2:00:02 PM 
1 7/29/2010 9:15:00 AM -37.5 -1  
1 7/29/2010 12:00:00 PM -90  -1  
1 7/29/2010 12:45:01 PM -12.5 -1  
1 7/29/2010 12:45:02 PM 0  0  
1 7/29/2010 12:45:03 PM -75  1  
1 7/29/2010 2:15:00 PM 23  1 -52  SUM of profit(row 22 to row 23) going back to 7/29/2010 12:45:02 PM 

すべてのSID。単純化のために1つのSIDを含めました。考えは、利益= 0と単位= 0を持つ行の現在の日または前日のいずれかを振り返ることです。その行が見つかると、すべての利益値を合計します。

このたびは、ありがとうございます。ありがとうございます。

+0

'純利益の列の合計は2で取られています。毎日15PM - どのように?つまり、手作業で行ったり、エージェントの仕事をしたりしていますか?あなたの例では毎日午後2時15分に行があり、これには利益値も含まれています。そのような行がない場合はどうなりますか?別の終末利益値を追加するために、午後2時15分の時間と利益0を挿入するか、またはスクリプトが最新の行を利益で検索し、そこには利益がありますか? –

+0

Sdateは一意の制約を持つ列ですか?データはどのように挿入されますか?最初にSdate M/dd/yyyy 2:15:00 PMのレコードを挿入してから、終値利益を計算しますか? – boes

+0

@Frans、sdateは一意の制約を持つ列ではありません。 m/dd/yyyy 2:15 PMで示される終了日レコードは、これらのレコードを生成するプロセスが実行されるときにテーブルに格納されます。 – ARK

答えて

1

私はデータベースにアクセスしてテストすることはできません。しかし、テーブル変数@tを設定してみてください。

declare @t table (SID int, Sdate datetime, profit decimal(9,1), units int) 

<populate it> 

各SIDのリストが必要です。私はそれを誤解した。私はこれに対する私の答えを変えたい。

select SID, Sdata, (select sum(Profit) from @t where Sdate between s.start and s.Sdate and S.SID = SID) profit, Units from 
(select SID, Sdata, (select max(Sdata) from @t where profit = 0 and unit = 0 and Sdata < t.Sdate and SID = t.SID) start from @t t 
where DATEPART(MINUTE, t.Sdata) =15 AND DATEPART(HOUR, t.Sdata) = 14 AND DATEPART(SECOND, t.Sdata) = 0) s 
ORDER BY SID, Sdate 
+0

クエリが必要な結果を生成します。回答として宣言する前に、この1つのSID以上の結果を2回確認したいと思います。応答してくれてありがとう。 – ARK

+0

私はちょうど結果を検証し終わった。クエリは正常に動作します。あなたの助けに感謝します。 – ARK

1

DDL &サンプルデータ:

CREATE TABLE atable (
    SID int, 
    Sdate datetime, 
    Profit money, 
    Units int 
); 
INSERT INTO atable (SID, Sdate, Profit, Units) 
SELECT 1, '7/26/2010 9:15:00 AM' , -37.5, -1 UNION ALL  
SELECT 1, '7/26/2010 12:00:00 PM', -125 , -1 UNION ALL  
SELECT 1, '7/26/2010 12:45:01 PM', -12.5, -1 UNION ALL  
SELECT 1, '7/26/2010 12:45:02 PM', 0 , 0 UNION ALL  
SELECT 1, '7/26/2010 12:45:03 PM', -75 , 1 UNION ALL  
SELECT 1, '7/26/2010 2:00:01 PM' , -12.5, 1 UNION ALL  
SELECT 1, '7/26/2010 2:00:02 PM' , 0 , 0 UNION ALL  
SELECT 1, '7/26/2010 2:00:03 PM' , -125 , -1 UNION ALL  
SELECT 1, '7/26/2010 2:15:00 PM' , -50 , -1 UNION ALL 
SELECT 1, '7/27/2010 9:15:00 AM' , 25 , -1 UNION ALL  
SELECT 1, '7/27/2010 12:00:00 PM', 196 , -1 UNION ALL  
SELECT 1, '7/27/2010 2:15:00 PM' , -12.5, -1 UNION ALL 
SELECT 1, '7/28/2010 9:15:00 AM' , 425 , -1 UNION ALL  
SELECT 1, '7/28/2010 12:00:00 PM', -125 , -1 UNION ALL  
SELECT 1, '7/28/2010 2:15:00 PM' , -12.5, -1 UNION ALL 
SELECT 1, '7/29/2010 9:15:00 AM' , -37.5, -1 UNION ALL  
SELECT 1, '7/29/2010 12:00:00 PM', -90 , -1 UNION ALL  
SELECT 1, '7/29/2010 12:45:01 PM', -12.5, -1 UNION ALL  
SELECT 1, '7/29/2010 12:45:02 PM', 0 , 0 UNION ALL  
SELECT 1, '7/29/2010 12:45:03 PM', -75 , 1 UNION ALL  
SELECT 1, '7/29/2010 2:15:00 PM' , 23 , 1; 

クエリ:

WITH ranges AS (
    SELECT 
    t.SID, 
    t.Sdate, 
    t.Units, 
    SdateStart = MAX(t0.Sdate) 
    FROM atable t 
    INNER JOIN atable t0 
     ON t0.SID = t.SID AND t0.Sdate < t.Sdate 
     AND t0.Profit = 0 AND t0.Units = 0 
    WHERE DATEPART(HH, t.Sdate) = 14 
    AND DATEPART(MI, t.Sdate) = 15 
    GROUP BY 
    t.SID, 
    t.Sdate, 
    t.Units 
) 
SElECT 
    r.SID, 
    r.Sdate, 
    Profit = SUM(t.Profit), 
    r.Units 
FROM ranges r 
    INNER JOIN atable t ON t.SID = r.SID 
    AND t.Sdate BETWEEN r.SdateStart AND r.Sdate 
GROUP BY 
    r.SID, 
    r.Sdate, 
    r.Units; 

出力は:

SID   Sdate     Profit    Units 
----------- ----------------------- --------------------- ----------- 
1   2010-07-26 14:15:00.000 -175.00    -1 
1   2010-07-27 14:15:00.000 33.50     -1 
1   2010-07-28 14:15:00.000 321.00    -1 
1   2010-07-29 14:15:00.000 -52.00    1 
+0

@Andriy M、データベースに対してこのクエリを実行しようとしているときに、 "範囲"内のSID = 1という基準を使用してデータをフィルタリングしようとしました。その空の結果を返します。なぜ私は分からない。 – ARK

+0

@Andriy M、決して気にしないでください。私はそのページをリフレッシュしませんでした。私は改訂されたクエリを実行しました。そしてそれはうまくいった。ご協力いただきありがとうございます。その価値については、ctはサブクエリバージョンよりも速く実行されているようです。 =) – ARK

+0

私のバージョンでのソートによるパフォーマンスの違いはありませんか? –