简体   繁体   English

SQL Server存储过程中的datetime参数选择数据

[英]SQL Server stored procedure datetime parameter on selecting data

I have a football league database and I am trying to get the current score of the teams on a specific date. 我有一个足球联赛数据库,我正在尝试获取特定日期球队的当前得分。 If I type in a date in the past I want the score at that specific date - the points of each teams on that date. 如果我输入过去的日期,我希望获得该特定日期的分数-每个团队在该日期的分数。

In my database I have a table that includes all the matches and I have a table with the teams and their point (this table is actually the same as the current score). 在我的数据库中,我有一个包含所有比赛的表格,并且我有一个包含球队及其得分的表格(该表格实际上与当前得分相同)。

The two tables are: 这两个表是:

 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
 )

I am trying to use a stored procedure where I have a datetime as a parameter to show the current score (the team table) at that date defined by the parameter. 我正在尝试使用一个存储过程,其中有一个datetime作为参数,以显示该参数定义的那个日期的当前得分(团队表)。

Right now I'm selecting all the matches that is bigger (newer) than the date I want til score table from and subtracting the result of that match from the teams point. 现在,我要选择所有比(直到)我想要直到截止得分表的日期更大(更新)的比赛,并从球队得分中减去该比赛的结果。

But it seems to me that it is a lot of work to do for something that simple. 但是在我看来,要做这么简单的事情需要做很多工作。

Does anyone have a better idea? 有谁有更好的主意吗?

Why do you subtract? 为什么要减去? Seems to me that the correct way to go would be to take the league start date and calculate the scores from that day up to selected date. 在我看来,正确的做法是取得联赛开始日期并计算从当天到选定日期的得分。

I'm not sure why you would want to put such a simple query into a procedure, but essentially what you're asking is as follows: 我不确定为什么要在过程中放入这样一个简单的查询,但是实际上您要问的是以下内容:

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

What Fedor says is correct - it is more efficient to do a single calculation from the beginning of time, than to have to do a calc from two different tables. Fedor所说的是正确的-从开始就进行一次计算比从两个不同的表进行计算要有效。

I would first transform the matches table like this: 我首先要像这样转换matches表:

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

Now it's easier to calculate the necessary totals: 现在,更容易计算所需的总数:

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

Next step would be to join the last result set to the teams table to get the team's names. 下一步是将最后一个结果集加入到teams表中,以获取团队的名称。 And if you actually need that final step, you could, of course, perform the calculations the way you intended from the beginning, ie calculate only the stats you need to subtract from the current values, rather than the actual standings. 而且,如果您实际上需要最后一步,那么您当然可以从一开始就按照预期的方式执行计算,即仅计算需要从当前值中减去的统计信息,而不是实际的排名。 So, using this inverted logic, the entire query might look like this: 因此,使用此反向逻辑,整个查询可能如下所示:

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

Note: You didn't specify which kind of football you meant, but living in Europe, it was easier for me to assume association football rather than any other kind. 注意:您没有指定足球的意思,但是住在欧洲,对我来说,参加协会橄榄球比其他任何一种都容易。 Yet, because I was not sure, I decided to parametrise my query. 但是,由于不确定,我决定对查询进行参数化。 That is why you can see all those @winpoints , @drawpoints and @losspoints placeholders. 这就是为什么您可以看到所有这些@winpoints@drawpoints@losspoints占位符的原因。 You can replace the variables with the actual constants, if you like, or you could leave the query parametrised in case you wanted to satisfy your curiosity as to what the team's standings would have been if a different scoring system were in effect. 如果愿意,可以将变量替换为实际的常数,也可以保留参数化的查询,以防您好奇,如果采用不同的评分系统,团队的地位将是什么样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从VBA使用datetime参数调用SQL Server存储过程? - How to call SQL Server stored procedure with datetime parameter from VBA? 从 Crystal Reports 到 SQL Server 存储过程的日期时间参数格式 - Datetime parameter format from Crystal Reports to SQL Server stored procedure 为什么SQL Server存储过程将加密数据选择为变量失败 - Why SQL Server stored procedure selecting encrypted data into variable fails SQL Server存储过程-将数据类型varchar转换为datetime时出错 - SQL Server stored procedure - error converting data type varchar to datetime SQL Server存储过程参数 - SQL Server Stored Procedure Parameter 在SQL Server中使用空数据参数调用存储过程 - Call Stored Procedure with Null Data Parameter in SQL Server SQL Server存储过程输出参数并从select返回数据 - SQL Server stored procedure output parameter and return data from select SQL Server中具有可选DateTime参数的存储过程 - Stored Procedure with Optional DateTime Parameters in SQL Server SQL Server中存储过程的日期时间问题 - Datetime issue with stored procedure in SQL Server SQL Server存储过程:datetime参数有时是错误的格式,具体取决于country的dateformat - SQL Server stored procedure: datetime parameter is wrong format sometimes depending on dateformat of country
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM