【问题标题】:Replacing hard coded values with a lookup table用查找表替换硬编码值
【发布时间】:2016-06-20 04:09:49
【问题描述】:

我想在我的 case 语句中使用查找表而不是使用硬编码值来确定设置边界。我没有做过任何类型的查找表,所以只是想要指导如何编写以下代码。

我有一个名为“ScoreReference”的表格,它显示以下内容:

如何在我的 CASE 语句中使用此查找表来替换硬编码值?

SELECT
TeamScore,
CASE WHEN TeamScore BETWEEN 11 AND 25  --Home Team Wins by 1 goal
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 1 ORDER BY NEWID())
     WHEN TeamScore BETWEEN 26 AND 40  --Home Team Wins by 2 goals
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 2 ORDER BY NEWID())
     WHEN TeamScore BETWEEN 41 AND 55  --Home Team Wins by 3 goals
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 3 ORDER BY NEWID())
     WHEN TeamScore BETWEEN 56 AND 70  --Home Team Wins by 4 goals
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 4 ORDER BY NEWID())
     WHEN TeamScore > 71  --Home Team Wins by 5 goals
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 5 ORDER BY NEWID())
    WHEN TeamScore BETWEEN -25 AND -11 --Away Team Wins by 1 goal
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -1 ORDER BY NEWID())
    WHEN TeamScore BETWEEN -40 AND -26  --Away Team Wins by 2 goals
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -2 ORDER BY NEWID())
    WHEN TeamScore BETWEEN -55 AND -41  --Away Team Wins by 3 goals
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -3 ORDER BY NEWID())
    WHEN TeamScore BETWEEN -70 AND -56  --Away Team Wins by 4 goals
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -4 ORDER BY NEWID())
    WHEN TeamScore <= -71  --Away Team Wins by 5 goals
        THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -5 ORDER BY NEWID())    
    ELSE (SELECT TOP 1 ScoreID FROM dbo.Score WHERE ScoreDifference = 0 ORDER BY NEWID()) -- Draw
END AS ScoreID

更新:

下面是“分数”表:

正如你所看到的,我想要做的是根据每支球队的权重(一个球队的权重是主队,另一个是客队'),权重的差异会反映在比分上。例如,如果两队之间的权重相差 11 -25,则得分差异为“1”,这意味着从“得分”表中,我们将随机选择差异为“1”的得分。

两个表的日期设置:

分数参考:

CREATE TABLE [dbo].[ScoreReference]
(
    [ScoreReferenceID] TINYINT IDENTITY (1,1) NOT NULL PRIMARY KEY, 
    [HomeWeighting] INT NULL, 
    [AwayWeighting] INT NULL, 
    [ScoreDifference] INT NULL
)

得分:

CREATE TABLE [dbo].[Score]
(
    [ScoreID] INT IDENTITY(1,1) NOT NULL PRIMARY KEY, 
    [HomeScore] INT NULL, 
    [AwayScore] INT NULL,
    [ScoreDifference] INT NULL
)

夹具:

CREATE TABLE [dbo].[Fixture](
    [FixtureID] INT NOT NULL PRIMARY KEY,
    [WeekNumber] TINYINT NOT NULL,
    [FixtureDate] DATE NULL,
    [HomeTeamID] TINYINT NULL,
    [HomeScore] INT NULL,
    [AwayTeamID] TINYINT NULL,
    [AwayScore] INT NULL,
    [HomeTeamResult] CHAR(1) NULL,
    [AwayTeamResult] CHAR(1) NULL,
    [LeagueID] TINYINT CONSTRAINT FK_Fixture_League FOREIGN KEY REFERENCES League(LeagueID)
)

团队加权:

WITH pl AS (SELECT DISTINCT p.PlayerID
                            ,p.Position
                            ,CASE WHEN p.TeamID = 0 THEN 0
                                  ELSE p.playerWeighting END AS playerWeighting
                            ,ABS(CHECKSUM(NewID())) % 10 + 1 AS Form
                            ,t.TeamID
            FROM dbo.Fixture f
            INNER JOIN dbo.League l ON f.LeagueID = l.LeagueID
            INNER JOIN dbo.Team t ON l.LeagueID = t.LeagueID
            INNER JOIN dbo.Player p ON t.TeamID = p.TeamID
            WHERE f.WeekNumber = 1)
,po AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY pl.TeamID, pl.Position ORDER BY NEWID()) AS Rnk FROM pl)
SELECT TeamID
    ,SUM(po.playerWeighting) AS TeamWeight
    ,Form--ABS(CHECKSUM(NewID())) % 10 + 1 AS Form
    ,SUM(po.playerWeighting / 10 * Form + po.playerWeighting) AS FinalTeamWeight
FROM po
WHERE (po.Position = 'GK' and po.rnk = 1) OR 
        (po.Position = 'DF' and po.rnk <= 4) OR
        (po.Position = 'MF' and po.rnk <= 4) OR
        (po.Position = 'FW' and po.rnk <= 2)
        GROUP BY po.TeamID

以下是 TeamScore:

;WITH cte AS
(
    SELECT f.FixtureID,
        ht.FinalTeamWeight - at.FinalTeamWeight AS TeamScore
    FROM dbo.Fixture f
    OUTER APPLY
    (
        SELECT tw.FinalTeamWeight
        FROM dbo.TeamWeighting tw
        WHERE tw.TeamID = f.HomeTeamID
    ) ht --HomeTeam
    OUTER APPLY
    (
        SELECT tw.FinalTeamWeight
        FROM dbo.TeamWeighting tw
        WHERE tw.TeamID = f.AwayTeamID
    ) at --AwayTeam
    WHERE f.HomeScore IS NULL AND f.FixtureDate < GETDATE()
)

最新代码:

;WITH cte AS
(
    SELECT f.FixtureID,
        ht.FinalTeamWeight - at.FinalTeamWeight AS TeamScore
    FROM dbo.Fixture f
    OUTER APPLY
    (
        SELECT tw.FinalTeamWeight
        FROM dbo.TeamWeighting tw
        WHERE tw.TeamID = f.HomeTeamID
    ) ht --HomeTeam
    OUTER APPLY
    (
        SELECT tw.FinalTeamWeight
        FROM dbo.TeamWeighting tw
        WHERE tw.TeamID = f.AwayTeamID
    ) at --AwayTeam
    WHERE f.HomeScore IS NULL AND f.FixtureDate < GETDATE()
)


UPDATE f 
SET f.HomeScore = s.HomeScore,
    f.AwayScore = s.AwayScore
FROM dbo.Fixture f
INNER JOIN 
(
    SELECT FixtureID,
    TeamScore
    ,( SELECT
            CASE
            WHEN c.TeamScore BETWEEN HomeWeighting AND AwayWeighting AND HomeScore > AwayScore  AND s.ScoreDifference = Sr.ScoreDifference
                THEN S.ScoreID  
            WHEN c.TeamScore BETWEEN AwayWeighting AND HomeWeighting AND HomeScore < AwayScore  AND s.ScoreDifference = Sr.ScoreDifference
                THEN S.ScoreID 
            WHEN c.TeamScore BETWEEN HomeWeighting AND AwayWeighting AND HomeScore = AwayScore  AND s.ScoreDifference = Sr.ScoreDifference
                THEN S.ScoreID 
            END  
        --CASE WHEN TeamScore BETWEEN 11 AND 25  --Home Team Wins by 1 goal
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 1 ORDER BY NEWID())
        -- WHEN TeamScore BETWEEN 26 AND 40  --Home Team Wins by 2 goals
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 2 ORDER BY NEWID())
        -- WHEN TeamScore BETWEEN 41 AND 55  --Home Team Wins by 3 goals
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 3 ORDER BY NEWID())
        -- WHEN TeamScore BETWEEN 56 AND 70  --Home Team Wins by 4 goals
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 4 ORDER BY NEWID())
        -- WHEN TeamScore > 71  --Home Team Wins by 5 goals
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore > AwayScore AND ScoreDifference = 5 ORDER BY NEWID())
        -- WHEN TeamScore BETWEEN -25 AND -11 --Away Team Wins by 1 goal
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -1 ORDER BY NEWID())
        -- WHEN TeamScore BETWEEN -40 AND -26  --Away Team Wins by 2 goals
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -2 ORDER BY NEWID())
        -- WHEN TeamScore BETWEEN -55 AND -41  --Away Team Wins by 3 goals
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -3 ORDER BY NEWID())
        -- WHEN TeamScore BETWEEN -70 AND -56  --Away Team Wins by 4 goals
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -4 ORDER BY NEWID())
        -- WHEN TeamScore <= -71  --Away Team Wins by 5 goals
        --  THEN (SELECT TOP 1 ScoreID FROM dbo.Score WHERE HomeScore < AwayScore AND ScoreDifference = -5 ORDER BY NEWID())    
     --   ELSE (SELECT TOP 1 ScoreID FROM dbo.Score WHERE ScoreDifference = 0 ORDER BY NEWID()) -- Draw
    FROM dbo.Score s
    LEFT JOIN dbo.ScoreReference sr
    ON s.sr.ScoreReferenceId = sr.ScoreReferenceId
)
    FROM cte c
 ) AS ScoreResult
    ON f.FixtureID = ScoreResult.FixtureID
--INNER JOIN Score s
--  ON score.ScoreID = s.ScoreID

预期输出:

【问题讨论】:

  • Score表和ScoreReferenceTable有关系吗?可能是外键。分数表中的一些示例数据会有所帮助。
  • @Sam 我注意到实际上在 sCore 和 ScoreReference 之间提供了一个参考。也许这是我的逻辑失败,我应该这样做。现在假设 ScoreReferenceID 与 ScoreID 相关联,我将发布 Score 表的示例
  • @Sam 我提供了对问题的更新,其中包括“分数”表和对我要完成的工作的解释。如果您需要更多信息,请告诉我
  • 谢谢。现在它更清楚了。然而 TeamScore 字段从何而来?
  • 您的 SQL 选择列 TeamScore... 从什么?您的选择返回多少行?您可以使用BETWEEN 将其加入您的查找表,但结果将只是ScoreReferenceID。这如何适应?

标签: sql sql-server


【解决方案1】:

我不完全确定您要完成什么,但如果您保证每个结果都有一个 ScoreDifference 匹配项,也许下面的内容会有所帮助。

select *
from (
    select *,
        DiffScore = HomeScore - AwayScore
    from Score) s
join ScoreReference sr
    on s.DiffScore = sr.ScoreDifference;

您能否提供一个更具体的示例数据集等?

【讨论】:

  • @Yobix 我提供了对问题的更新,其中包括“分数”表和对我要完成的工作的解释。如果您需要更多信息,请告诉我
【解决方案2】:

您可以尝试类似的方法。因为我没有数据,有些表无法检查出来。但是试试这个,稍微调整一下,让我知道。

SELECT 
    c.TeamScore
    ,(  SELECT 
            CASE
            WHEN c.TeamScore BETWEEN HomeWeighting AND AwayWeighting AND HomeScore > AwayScore  AND S.ScoreDifference = SF.ScoreDifference
                THEN S.ScoreID  
            WHEN c.TeamScore BETWEEN AwayWeighting AND HomeWeighting AND HomeScore < AwayScore  AND S.ScoreDifference = SF.ScoreDifference
                THEN S.ScoreID 
            END  
        FROM    dbo.Score S
        LEFT JOIN dbo.ScoreReference  SF
            ON S.SF.ScorereferenceId = SF.ScorereferenceId
        )
FROM    cte c

【讨论】:

  • 我会在我上班大约一个小时的时候试一试,Sam,谢谢。会让你知道结果
  • 嗨,Sam,对您的答案进行了一些调整,但仍然无法正常工作。我已经发布了有问题的最新代码,你能看到任何问题吗?
  • 我现在可以看到输出和预期的输出类型,以便我可以知道哪里出了问题吗?
  • 输出似乎没有在夹具表的行中显示任何内容。预期的输出显示在最新更新的问题中,因为它目前使用硬编码值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-04
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多