2012-03-05 15 views
0

私はサッカーリーグのデータベースを持っており、特定の日付にチームの現在のスコアを取得しようとしています。私が過去に日付を入力した場合、その特定の日付のスコア - その日付の各チームのポイントが必要になります。データ選択時のSQL Serverストアドプロシージャdatetimeパラメータ

私のデータベースには、すべての試合が含まれているテーブルがあり、チームとそのポイントのテーブルがあります(このテーブルは実際のスコアと同じです)。

二つのテーブルは以下のとおりです。

create table teams 
(
id char(3) primary key, 
name varchar(40), 
nomatches int, 
owngoals int, 
othergoals int, 
points int 
) 

create table matches 
(
id int identity(1,1), 
homeid char(3) foreign key references teams(id), 
outid char(3) foreign key references teams(id), 
homegoal int, 
outgoal int, 
matchdate datetime 
) 

私はパラメータで定義されたその日に現在のスコア(チーム表)を表示するために、私は、パラメータとしてdatetimeを持つストアドプロシージャを使用しようとしています。

今、私は、スコア表を作成する日付よりも大きい(より新しい)すべてのマッチを選択し、そのマッチの結果をチームポイントから差し引いています。

しかし、それは単純なことのためにやることはたくさんあると思います。

もっと良いアイデアはありますか?

答えて

0

なぜあなたは減算しますか?リーグの開始日を決め、その日から選んだ日までの得点を計算するのが正しい方法だと私には思えます。

+0

私はチームが今現在の時点で持っているポイントからそれを引きます。それはほぼ同じです - もし私が最初の日付から選択された日付まで計算したり、現在の日付から現在の日付まで現在のポイントからマッチ結果を差し引くのであれば - そうではありませんか? – Anne

0

私はあなたが手順にこのような単純なクエリを置きたいと思う理由はわからないんだけど、次のように基本的に何を求めていることは次のとおりです。

CREATE PROCEDURE sp_goals_to_date(@todate DATETIME) AS  
    SELECT id, SUM(homegoal) AS homegoal, SUM(outgoal) AS outgoal FROM matches WHERE matchdate <= @mydate 

何ヒョードルが言うことは正しいです - それはもっとあります2つの異なるテーブルから1つの計算を実行するよりも、初めから1つの計算を効率的に行うことができます。

0

私が最初にこのようなmatchesテーブル変換になります。次のステップはteamsに最後の結果セットに参加するだろう

SELECT 
    teamid, 
    nomatches = COUNT(*), 
    owngoals = SUM(owngoal), 
    othergoals = SUM(othergoal), 
    points  = SUM(points) 
FROM transformed_matches 
GROUP BY 
    teamid 

SELECT 
    teamid = CASE t.calchometeam WHEN 1 THEN m.homeid ELSE m.outid END, 
    owngoal = CASE t.calchometeam WHEN 1 THEN m.homegoal ELSE m.outgoal END, 
    othergoal = CASE t.calchometeam WHEN 0 THEN m.homegoal ELSE m.outgoal END, 
    points = CASE m.homegoal 
    WHEN m.outgoal THEN @drawpoints 
    ELSE (SIGN(m.homegoal - m.outgoal) + 1)/2^~m.playedhome) * @winpoints 
     + (SIGN(m.homegoal - m.outgoal) + 1)/2^m.playedhome) * @losspoints 
    END 
FROM matches m 
CROSS JOIN (
    SELECT CAST(0 AS bit) UNION ALL 
    SELECT CAST(1 AS bit) 
) AS t (calchometeam) 
WHERE m.matchdate <= @givendate 

今では、必要な合計を計算する方が簡単ですがテーブルを使用してチームの名前を取得します。実際に最後のステップが必要な場合は、最初から意図したとおりに計算を実行できます。つまり、実際の順位ではなく現在の値から減算する必要がある統計のみを計算できます。

WITH 
transformed_matches AS (
    SELECT 
    matchid = m.id, 
    teamid = CASE t.calchometeam WHEN 1 THEN m.homeid ELSE m.outid END, 
    owngoal = CASE t.calchometeam WHEN 1 THEN m.homegoal ELSE m.outgoal END, 
    othergoal = CASE t.calchometeam WHEN 0 THEN m.homegoal ELSE m.outgoal END, 
    points = CASE m.homegoal 
     WHEN m.outgoal THEN @drawpoints 
     ELSE (SIGN(m.homegoal - m.outgoal) + 1)/2^~m.playedhome) * @winpoints 
     + (SIGN(m.homegoal - m.outgoal) + 1)/2^m.playedhome) * @losspoints 
    END 
    FROM matches m 
    CROSS JOIN (
    SELECT CAST(0 AS bit) UNION ALL 
    SELECT CAST(1 AS bit) 
) AS t (calchometeam) 
    WHERE m.matchdate > @givendate 
), 
aggregated AS (
    SELECT 
    teamid, 
    nomatches = COUNT(*), 
    owngoals = SUM(owngoal), 
    othergoals = SUM(othergoal), 
    points  = SUM(points) 
    FROM transformed_matches 
    GROUP BY 
    teamid 
) 
SELECT 
    t.id, 
    t.name, 
    nomatches = t.nomatches - ISNULL(a.nomatches , 0), 
    owngoals = t.owngoals - ISNULL(a.orngoals , 0), 
    othergoals = t.nomatches - ISNULL(a.othergoals, 0), 
    points  = t.points  - ISNULL(a.points , 0) 
FROM teams t 
    LEFT JOIN aggregated a ON t.id = a.teamid 

注::だから、この反転論理を使用して、クエリ全体は次のようになりますあなたが意味フットボールの種類を指定していないが、私はサッカーを前提とするためにヨーロッパに住んで、それは簡単でした他の種類よりむしろ。しかし、私は確信が持てなかったので、私はクエリをパラメートライズすることに決めました。そのため、@winpoints@drawpoints@losspointsのプレースホルダがすべて表示されます。必要に応じて変数を実際の定数に置き換えることができます。あるいは、異なるスコアリングシステムが有効であった場合のチームの順位について、好奇心を満たすためにクエリをパラメータ化したままにすることができます。

関連する問題