SQL Server子查询返回错误

时间:2014-04-19 00:57:05

标签: sql sql-server

当我尝试执行我的语句时,我收到一条错误,返回“Subquery返回的值超过1。不允许......”,你知道其余的。我对子查询并不擅长,事实上它有时会在试验和错误中猜测,直到我看到我想要收集的结果。任何人都可以向我解释为什么它会因为这个错误而返回?

我试图返回一个人游戏的分数,然后继续从同一个游戏中返回所有玩家。

如果数据相关,则文件在此处:SQL File

SELECT
 TP.intPlayerID
,TP.strLastName + ', ' + TP.strFirstName AS strPlayerName
,TG.*
,TR.intGameID
,(
    SELECT
        CASE WHEN Game.F1S1 = 10 and Game.F2S1 = 10 THEN 20 + Game.F3S1
             WHEN Game.F1S1 = 10 and Game.F2S1 < 10 THEN 10 + Game.F2S1 + Game.F2S2
             WHEN Game.F1S1 + Game.F1S2 = 10 THEN 10 + Game.F2S1
             ELSE Game.F1S1 + Game.F1S2 
             END
        +
        CASE WHEN Game.F2S1 = 10 and Game.F3S1 = 10 THEN 20 + Game.F4S1
             WHEN Game.F2S1 = 10 and Game.F3S1 < 10 THEN 10 + Game.F3S1 + Game.F3S2
             WHEN Game.F2S1 + Game.F2S2 = 10 THEN 10 + Game.F3S1
             ELSE Game.F2S1 + Game.F2S2
             END
        +
        CASE WHEN Game.F3S1 = 10 and Game.F4S1 = 10 THEN 20 + Game.F5S1
             WHEN Game.F3S1 = 10 and Game.F4S1 < 10 THEN 10 + Game.F4S1 + Game.F4S2
             WHEN Game.F3S1 + Game.F3S2 = 10 THEN 10 + Game.F4S1
             ELSE Game.F3S1 + Game.F3S2
             END
        +
        CASE WHEN Game.F4S1 = 10 and Game.F5S1 = 10 THEN 20 + Game.F6S1
             WHEN Game.F4S1 = 10 and Game.F5S1 < 10 THEN 10 + Game.F5S1 + Game.F5S2
             WHEN Game.F4S1 + Game.F4S2 = 10 THEN 10 + Game.F5S1
             ELSE Game.F4S1 + Game.F4S2
             END
        +
        CASE WHEN Game.F5S1 = 10 and Game.F6S1 = 10 THEN 20 + Game.F7S1
             WHEN Game.F5S1 = 10 and Game.F6S1 < 10 THEN 10 + Game.F6S1 + Game.F6S2
             WHEN Game.F5S1 + Game.F5S2 = 10 THEN 10 + Game.F6S1
             ELSE Game.F5S1 + Game.F5S2
             END
        +
        CASE WHEN Game.F6S1 = 10 and Game.F7S1 = 10 THEN 20 + Game.F8S1
             WHEN Game.F6S1 = 10 and Game.F7S1 < 10 THEN 10 + Game.F7S1 + Game.F7S2
             WHEN Game.F6S1 + Game.F6S2 = 10 THEN 10 + Game.F7S1
             ELSE Game.F6S1 + Game.F6S2
             END
        +
        CASE WHEN Game.F7S1 = 10 and Game.F8S1 = 10 THEN 20 + Game.F9S1
             WHEN Game.F7S1 = 10 and Game.F8S1 < 10 THEN 10 + Game.F8S1 + Game.F8S2
             WHEN Game.F7S1 + Game.F7S2 = 10 THEN 10 + Game.F8S1
             ELSE Game.F7S1 + Game.F7S2
             END
        +
        CASE WHEN Game.F8S1 = 10 and Game.F9S1 = 10 THEN 20 + Game.F10S1
             WHEN Game.F8S1 = 10 and Game.F9S1 < 10 THEN 10 + Game.F9S1 + Game.F9S2
             WHEN Game.F8S1 + Game.F8S2 = 10 THEN 10 + Game.F9S1
             ELSE Game.F8S1 + Game.F8S2
             END
        +
        CASE WHEN Game.F9S1 = 10 and Game.F10S1 = 10 THEN 20 + Game.F10S2
             WHEN Game.F9S1 = 10 and Game.F10S1 < 10 THEN 10 + Game.F10S1 + Game.F10S2
             WHEN Game.F9S1 + Game.F9S2 = 10 THEN 10 + Game.F10S1
             ELSE Game.F9S1 + Game.F9S2
             END
        +
        CASE WHEN Game.F10S1 = 10 and Game.F10S2 = 10 THEN 20 + Game.F10S3
             WHEN Game.F10S1 = 10 and Game.F10S2 < 10 THEN 10 + Game.F10S2 + Game.F10S3
             WHEN Game.F10S1 + Game.F10S2 = 10 THEN 10 + Game.F10S3
             ELSE Game.F10S1 + Game.F10S2
             END 
        AS GameScore
    FROM 
        (   
            SELECT
                TR.intGameID
                ,SUM( CASE WHEN TR.intRollIndex = 1 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F1S1
                ,SUM( CASE WHEN TR.intRollIndex = 1 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F1S2
                ,SUM( CASE WHEN TR.intRollIndex = 2 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F2S1
                ,SUM( CASE WHEN TR.intRollIndex = 2 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F2S2
                ,SUM( CASE WHEN TR.intRollIndex = 3 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F3S1
                ,SUM( CASE WHEN TR.intRollIndex = 3 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F3S2
                ,SUM( CASE WHEN TR.intRollIndex = 4 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F4S1
                ,SUM( CASE WHEN TR.intRollIndex = 4 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F4S2
                ,SUM( CASE WHEN TR.intRollIndex = 5 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F5S1
                ,SUM( CASE WHEN TR.intRollIndex = 5 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F5S2
                ,SUM( CASE WHEN TR.intRollIndex = 6 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F6S1
                ,SUM( CASE WHEN TR.intRollIndex = 6 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F6S2
                ,SUM( CASE WHEN TR.intRollIndex = 7 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F7S1
                ,SUM( CASE WHEN TR.intRollIndex = 7 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F7S2
                ,SUM( CASE WHEN TR.intRollIndex = 8 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F8S1
                ,SUM( CASE WHEN TR.intRollIndex = 8 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F8S2
                ,SUM( CASE WHEN TR.intRollIndex = 9 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F9S1
                ,SUM( CASE WHEN TR.intRollIndex = 9 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F9S2
                ,SUM( CASE WHEN TR.intRollIndex = 10 and TR.intRollNumberIndex = 1 THEN TR.intNumberOfPins ELSE 0 END ) F10S1
                ,SUM( CASE WHEN TR.intRollIndex = 10 and TR.intRollNumberIndex = 2 THEN TR.intNumberOfPins ELSE 0 END ) F10S2
                ,SUM( CASE WHEN TR.intRollIndex = 10 and TR.intRollNumberIndex = 3 THEN TR.intNumberOfPins ELSE 0 END ) F10S3
            FROM
                TRolls AS TR
            GROUP BY
                TR.intGameID ) AS Game )
FROM
     TPlayers AS TP
    ,TGames AS TG
    ,TRolls AS TR
WHERE
    TP.intPlayerID = TG.intPlayerID
    AND TG.intGameID = TR.intGameID
    AND TP.intPlayerID = 21

1 个答案:

答案 0 :(得分:0)

如果没有表格设计,调试有点困难,但从我在查询中看到的情况来看,可能会出现一些问题(同样,取决于您的表格设计)。

  1. 您的内部子查询没有Where语句。因此,它 将所有游戏带入TROLls表,按intGameID分组;它会 返回多个游戏;这可能是“游戏”的问题 子查询在SELECT语句中使用,因此它应该只返回一行; 您可能需要在子查询中添加WHERE子句,以及 也许是另一个连接,取决于你的表结构和他们的 关系。如果你真的需要得到每场比赛的得分 (意思是,你还不知道游戏ID)你需要在那里做到这一点 FROM语句(不是像你一样在select语句中),像这样

    SELECT TP.intPlayerID ,TP.strLastName + ', ' + TP.strFirstName AS strPlayerName ,TG.* ,TR.intGameID ,Game.Gamescore FROM TPlayers AS TP ,TGames AS TG ,TRolls AS TR , (Select ... ... ) As Game WHERE ...

  2. 根据您的问题,我在游戏中了解您有多个玩家。 您只是过滤“PlayerID = 21”,因此您要添加所有内容 所有游戏中该玩家的得分 - 这是你真正想要的吗? 或者您是否缺少过滤特定游戏的其他条件?

  3. 你提到你不熟悉子查询,所以这里有一个快速的经验法则:

    • 如果在Select语句中使用(与您的一样),子查询只能 返回一排。总是。
    • 如果在From语句中使用(就像我的例子),它会带给你一个 具有多行的虚拟“临时表”,将其括起来 括号并使用别名来识别它;然后你加入吧 使用给定别名的From语句中的其他表。
    • 如果在Where语句中使用它应该返回一个布尔值(true 或者错误的),一个常见的例子是验证是否 不是某个地方存在信息,如下:

      WHERE EXISTS (SELECT 'X' from .... Where ....)