为什么SQL Server sql查询返回空列表?

时间:2015-09-04 08:06:33

标签: sql sql-server

请注意我知道它必须是简单的,可能是显而易见的 - 我只是看不到它...如上所述,你知道为什么这个SQL查询在SQL Server上执行时会返回空列表(通过SQL Server管理工作室),提供数据是否适当,并且查询的所有参数都设置正确?

这个问题与我的另一个问题(Does anyone know why JPQL query on a view with SQL Server does not work? 'GetResultList' always returns empty list)有关,但在这个阶段它实际上变成了一个单独的主题,所以我把它放在这里。这是查询:

SELECT t1.Id,
         t2.IdTransiti,
         t1.CodiceCaricoPericoloso,
         t1.Confidenza,
         t1.Istante,
         t1.IstanteRicezione,
         t2.SQLServer_latitude,
         t2.SQLServer_longitude,
         t1.Partizione,
         t1.Targa,
         t1.TargaSecondaria,
         t1.UtmcInstanceId,
         t1.VelocitaStimata,
         t1.IdColore,
         t1.IdCorsia,
         t1.IdMarca,
         t1.IdModello,
         t1.IdNazionalita,
         t1.IdSerie,
         t1.IdTipologiaVeicolo
    FROM dbo.TransitiView t1
    LEFT OUTER JOIN Serie t0
       ON (t0.Id = t1.IdSerie)
    LEFT OUTER JOIN dbo.Colori t3
       ON (t3.Id = t1.IdColore)
    LEFT OUTER JOIN Modelli t4
       ON (t4.Id = t1.IdModello)
    LEFT OUTER JOIN Marche t5
       ON (t5.Id = t1.IdMarca),
    TransitiPunti t2,
    Corsie t6
   WHERE ( ( ( ( ( (t6.Attiva = 1)
                  AND (t1.Istante BETWEEN '2015-09-03 00:16:50.693'
                                      AND '2015-09-03 23:16:50.693'))
                AND ( (t1.Partizione = 0) OR (t1.Partizione = 6)))
              AND (t1.IdCorsia = 1))
            AND (t2.IdTransiti = t1.Id))
          AND (t6.Id = t1.IdCorsia))
ORDER BY t1.Istante DESC

修改

感谢russ回答我现在知道发生了什么 - SQL Server不喜欢内连接中的空记录 - ODD !! 请问,你们中的任何一个人都知道如何以及是否有可能使SQL Server“LIKE”内连接在连接表的相应列中可能缺少条目?或者......至少如何使它适用于这个特定的查询?

我想这样做:...... ON(t2.IdTransiti = t1.Id或t2.IdTransiti为空)但这对SQL Server来说还不够好。它没有帮助:(。

奖金问题:当通过内部联接加入的表可能为空时,知道为什么它可以用于MySQL但不适用于SQL Server?为什么一开始就不行呢?

修改

回答问题: 感谢russ - 我基本上得到了它 - 这只是我的困惑,仅此而已。请在接受的答案下阅读评论。一切都源于我忘记的事实,不知道JPA中的@SecondaryTable注释转化为内连接然后双重混淆 - 我无视明显的内部联接在两个表格中显示值!

感谢大家的努力,我想在下次陈述事情之前我必须多思考一下:)。

2 个答案:

答案 0 :(得分:0)

如果您认为表[TransitiPunti]中没有记录,那么肯定会停止使用该查询的INNER JOIN生成行的任何查询。注意:您现有的查询确实在该表上使用了 INNER JOIN (它可以使用旧式语法,但它是一个内部联接)。

我建议您“逐步”测试,以便您可以解决问题。 “从小处开始”,尝试一下,如果成功一次添加一个项目并再试一次。

只要您停止获取结果,就会知道您添加的最后一项是什么,而且该项会导致问题。

例如,这里有3个要查询的查询。

/ *仅限一张桌子(t1)* /

SELECT
      t1.Id
    , t1.CodiceCaricoPericoloso
    , t1.Confidenza
    , t1.Istante
    , t1.IstanteRicezione
    , t1.Partizione
    , t1.Targa
    , t1.TargaSecondaria
    , t1.UtmcInstanceId
    , t1.VelocitaStimata
    , t1.IdColore
    , t1.IdCorsia
    , t1.IdMarca
    , t1.IdModello
    , t1.IdNazionalita
    , t1.IdSerie
    , t1.IdTipologiaVeicolo
FROM dbo.TransitiView t1
WHERE t1.Istante BETWEEN '2015-09-03 00:16:50.693' AND '2015-09-03 23:16:50.693'
      AND (t1.Partizione = 0 OR t1.Partizione = 6)
      AND t1.IdCorsia = 1
ORDER BY t1.Istante DESC
;

/ *两个表(t1& t6)* /

SELECT
      t1.Id
    , t1.CodiceCaricoPericoloso
    , t1.Confidenza
    , t1.Istante
    , t1.IstanteRicezione
    , t1.Partizione
    , t1.Targa
    , t1.TargaSecondaria
    , t1.UtmcInstanceId
    , t1.VelocitaStimata
    , t1.IdColore
    , t1.IdCorsia
    , t1.IdMarca
    , t1.IdModello
    , t1.IdNazionalita
    , t1.IdSerie
    , t1.IdTipologiaVeicolo
FROM dbo.TransitiView t1
      INNER JOIN Corsie t6 ON t6.Id = t1.IdCorsia
WHERE t6.Attiva = 1
      AND t1.Istante BETWEEN '2015-09-03 00:16:50.693' AND '2015-09-03 23:16:50.693'
      AND (t1.Partizione = 0 OR t1.Partizione = 6)
      AND t1.IdCorsia = 1
ORDER BY t1.Istante DESC
;

/ *三个表t1,t2,t6 * /

SELECT
      t1.Id
    , t2.IdTransiti
    , t1.CodiceCaricoPericoloso
    , t1.Confidenza
    , t1.Istante
    , t1.IstanteRicezione
    , t2.SQLServer_latitude
    , t2.SQLServer_longitude
    , t1.Partizione
    , t1.Targa
    , t1.TargaSecondaria
    , t1.UtmcInstanceId
    , t1.VelocitaStimata
    , t1.IdColore
    , t1.IdCorsia
    , t1.IdMarca
    , t1.IdModello
    , t1.IdNazionalita
    , t1.IdSerie
    , t1.IdTipologiaVeicolo
FROM dbo.TransitiView t1
      INNER JOIN TransitiPunti t2 ON t2.IdTransiti = t1.Id
      INNER JOIN Corsie t6 ON t6.Id = t1.IdCorsia
WHERE t6.Attiva = 1
      AND t1.Istante BETWEEN '2015-09-03 00:16:50.693' AND '2015-09-03 23:16:50.693'
      AND (t1.Partizione = 0 OR t1.Partizione = 6)
      AND t1.IdCorsia = 1
ORDER BY t1.Istante DESC

永远不要使用旧的连接语法和(更好的)显式ANSI连接的混合。

我也不喜欢多余的括号,我相信他们会混淆而不是帮助。

SELECT
      t1.Id
    , t2.IdTransiti
    , t1.CodiceCaricoPericoloso
    , t1.Confidenza
    , t1.Istante
    , t1.IstanteRicezione
    , t2.SQLServer_latitude
    , t2.SQLServer_longitude
    , t1.Partizione
    , t1.Targa
    , t1.TargaSecondaria
    , t1.UtmcInstanceId
    , t1.VelocitaStimata
    , t1.IdColore
    , t1.IdCorsia
    , t1.IdMarca
    , t1.IdModello
    , t1.IdNazionalita
    , t1.IdSerie
    , t1.IdTipologiaVeicolo
FROM dbo.TransitiView t1
      /*
      LEFT OUTER JOIN Serie t0 ON t0.Id = t1.IdSerie
      LEFT OUTER JOIN dbo.Colori t3 ON t3.Id = t1.IdColore
      LEFT OUTER JOIN Modelli t4 ON t4.Id = t1.IdModello
      LEFT OUTER JOIN Marche t5 ON t5.Id = t1.IdMarca
      */
      INNER JOIN TransitiPunti t2 ON t2.IdTransiti = t1.Id
      INNER JOIN Corsie t6 ON t6.Id = t1.IdCorsia
WHERE t6.Attiva = 1
      AND t1.Istante BETWEEN '2015-09-03 00:16:50.693' AND '2015-09-03 23:16:50.693'
      AND (t1.Partizione = 0 OR t1.Partizione = 6)
      AND t1.IdCorsia = 1
ORDER BY t1.Istante DESC

在取出括号并更正连接语法时,我认为查询如上所示。请注意,没有明显需要任何左连接表。

顺便说一句:

AND (t1.Partizione = 0 OR t1.Partizione = 6)

可以更改为:

AND t1.Partizione IN (0,6)

答案 1 :(得分:-1)

包围似乎不寻常,您可以尝试用以下方法替换当前的WHERE子句:

[Conditional("DEBUG"),Conditional("ANNA")]

如果transipunti表为空,请尝试:

WHERE t6.Attiva = 1 
AND (t1.Istante BETWEEN '2015-09-03 00:16:50.693' AND '2015-09-03 23:16:50.693')
AND (t1.Partizione = 0 OR t1.Partizione = 6)
AND t1.IdCorsia = 1
AND t2.IdTransiti = t1.Id
AND t6.Id = t1.IdCorsia
ORDER BY t1.Istante DESC

在SQL Server中使用Null友好的左连接:

SELECT t1.Id,
     t1.CodiceCaricoPericoloso,
     t1.Confidenza,
     t1.Istante,
     t1.IstanteRicezione,
     t1.Partizione,
     t1.Targa,
     t1.TargaSecondaria,
     t1.UtmcInstanceId,
     t1.VelocitaStimata,
     t1.IdColore,
     t1.IdCorsia,
     t1.IdMarca,
     t1.IdModello,
     t1.IdNazionalita,
     t1.IdSerie,
     t1.IdTipologiaVeicolo
FROM dbo.TransitiView t1
LEFT OUTER JOIN Serie t0
   ON (t0.Id = t1.IdSerie)
LEFT OUTER JOIN dbo.Colori t3
   ON (t3.Id = t1.IdColore)
LEFT OUTER JOIN Modelli t4
   ON (t4.Id = t1.IdModello)
LEFT OUTER JOIN Marche t5
   ON (t5.Id = t1.IdMarca),
Corsie t6
WHERE t6.Attiva = 1 
AND (t1.Istante BETWEEN '2015-09-03 00:16:50.693' AND '2015-09-03 23:16:50.693')
AND (t1.Partizione = 0 OR t1.Partizione = 6)
AND t1.IdCorsia = 1
AND t6.Id = t1.IdCorsia
ORDER BY t1.Istante DESC