Azure SQL 和 SQL 服务器标准之间的不同结果

Different outcomes between Azure SQL and SQL Server Standard

我在 SQL Server Standard 和 Azure SQL 中有相同的查询(见下文)。但遗憾的是,即使数据库中的数据相同,它们也没有相同的结果。 Vraag(即问题)有 12 行。回答了一个问题(userantword)。在 SQL 服务器上它显示 12 个问题,其中一个有 id_antwoord。其他为空。在 Azure 中,它只显示已回答的问题,而忽略其他问题。当我只有 select 个类别的问题时,它显示 12 个问题。

SELECT vraag.i_d__categorie, vraag.i_d, vraag.niveau, vraag.omschrijving, 
       vraag.volgorde, vraag.code, vraag.gewicht, vraag.tekst, vraag.thema1, 
       vraag.thema2, vraag.thema3, vraag.thema4, vraag.thema5, vraag.thema6, 
       userantwoord.id_antwoord
FROM   categorie 
       LEFT OUTER JOIN vraag 
         LEFT OUTER JOIN Users 
           INNER JOIN userantwoord 
           ON Users.UserId = userantwoord.Id_user 
         ON vraag.i_d = userantwoord.id_vraag 
       ON categorie.i_d = vraag.i_d__categorie

WHERE categorie.link = @Onderwerp AND vraag.niveau = @Niveau 
      AND ([Users].UserId = @UserID OR [Users].UserId is null)
ORDER BY vraag.volgorde

Userantword定义如下:

CREATE TABLE [dbo].[userantwoord](
[id] [uniqueidentifier] NOT NULL,
[id_antwoord] [uniqueidentifier] NULL,
[id_vraag] [uniqueidentifier] NULL,
[Id_user] [uniqueidentifier] NULL,
CONSTRAINT [PK_userantwoord] PRIMARY KEY CLUSTERED

在所有正确的地方都有外键。 有什么我忘了看的吗?我在互联网上搜索了 Azure en SQL 服务器之间的差异,但找不到如此基本的东西。

无论 Sql 服务器的版本和版本如何,我相信原始查询中存在潜在错误。看起来,您的要求是显示用户已回答的问题,因为:

  • 给定类别和级别的所有问题
  • 针对特定用户,或针对所有用户(取决于是否提供空过滤器)
  • 如果用户没有回答特定问题,userantwoord
  • 中将没有相应的行

我认为您不应该通过 userantwoord table 加入任何类型的联接,相反,您可以使用 CROSS JOIN 来获取所有问题的笛卡尔积对于给定的一个或多个用户,然后只有 LEFT JOINuserantwoord,对于不匹配的用户,这将 return NULL。

所以这里有一个替代方案:

SELECT vraag.id_categorie, vraag.id, vraag.niveau, vraag.omschrijving, 
       vraag.volgorde, vraag.code, users.Name, userantwoord.id_antwoord
FROM   dbo.categorie 
       INNER JOIN dbo.vraag 
         ON categorie.id = vraag.id_categorie
        CROSS JOIN dbo.Users 
        LEFT OUTER JOIN dbo.userantwoord 
        ON Users.UserId = userantwoord.Id_user AND vraag.id = userantwoord.id_vraag
WHERE categorie.link = @Onderwerp AND vraag.niveau = @Niveau 
      AND ([Users].UserId = @UserID OR @UserID is null) -- **
ORDER BY Users.Name, vraag.volgorde;

如果您只对单个用户使用查询,则不需要 @UserID is null 谓词。

SqlFiddle example here