【问题标题】:SQL Request with LEFT JOIN not able to find data带有 LEFT JOIN 的 SQL 请求无法找到数据
【发布时间】:2020-02-20 13:50:13
【问题描述】:

我正在处理我的 C# 项目,由于 .sql 过程,我必须从数据库中获取数据。

合成:

ProprietesCourantes 链接到表 Entite

Archive 链接到表 EntiteArchive

==> 我想在ProprietesCourantesArchive 之间建立一个链接,感谢字段Libellé

ProprietesCourantes

我有几张桌子:

SELECT TOP (1000) [IdEntite]
      ,[Libelle]
      ,[EstActif]
      , ...
      , ...
  FROM [Database].[dbo].[ProprietesCourantes]
  WHERE [Libelle] = 'DELTA SERVICE AUTO';

Entite

SELECT TOP (1000) [IdEntite]
      ,[TypeEntite]
      ,[CodeEntite]
      ,[TypeCodeEntite]
  FROM [Database].[dbo].[Entite]
  WHERE IdEntite = '165';

Archive

SELECT TOP (1000) [IdArchive]
      ,[IdEntite]
      ,[NoteFinale]
      ,[EstValide]
  FROM [Database].[dbo].[Archive]
  WHERE IdEntite = '33' and EstValide = '1';

EntiteArchive

SELECT TOP (1000) [IdEntite]
      ,[TypeEntite]
      ,[CodeEntite]
      ,[Libelle]
      ,...
  FROM [Database].[dbo].[EntiteArchive]

我的 SQL 请求:

SELECT
            ProprietesCourantes.IdEntite                                                                    as IdEntite, 
            ProprietesCourantes.Libelle                                                                     as RaisonSociale,
            Entite.CodeEntite                                                                               as IdCMCIC,
            ProprietesCourantes.NomParent                                                                   as NomGN,
            Archive.NoteFinale                                                                              as Cotation,
            Archive.DateValiditeQuestionnaireDeSoutien                                                      as DateValiditeQuestionnaireDeSoutien,
            ProprietesCourantes.CodePays                                                                    as Pays,
            ProprietesCourantes.EstActif                                                                    as Statut,
            CAST(CASE WHEN Entite.CodeEntite = ProprietesCourantes.IdSocMere THEN 1 ELSE 0 END AS BIT)      as EstMaisonMere,
            ProprietesCourantes.IdCMCICParent                                                               as IdCMCICParent,
            ProprietesCourantesGN.CodeAlgo                                                                  as CodeAlgoParent

    FROM ProprietesCourantes

    LEFT JOIN Archive   ON (Archive.IdEntite  = ProprietesCourantes.IdEntite and Archive.EstValide=1)
    LEFT JOIN Entite ON Entite.IdEntite = ProprietesCourantes.IdEntite
    LEFT JOIN Entite as EntiteGN ON EntiteGN.CodeEntite = ProprietesCourantes.IdCMCICParent
    LEFT JOIN ProprietesCourantes as ProprietesCourantesGN ON ProprietesCourantesGN.IdEntite = EntiteGN.IdEntite

    WHERE Entite.TypeEntite = 1 
        AND   (ProprietesCourantes.Libelle LIKE '%'+'DELTA SERVICE'+'%' )

如您所见:CotationDateValiditeQuestionnaireDeSoutien 为 NULL,因为 LEFT JOIN Archive ON (Archive.IdEntite = ProprietesCourantes.IdEntite 无法工作(不同的 IDEntite)。

我试图用这个替换,但它不起作用,知道吗?

LEFT JOIN Archive   ON ((select EntiteArchive.Libelle from EntiteArchive LEFT JOIN Archive ON (EntiteArchive.IdEntite = Archive.IdEntite)) = ProprietesCourantes.Libelle and Archive.EstValide=1)

【问题讨论】:

  • entite 的条件应该在on 子句中,而不是where 子句中。
  • @GordonLinoff 你能写一个例子来说明你的句子吗?
  • 换句话说,通过在左连接表的 WHERE 子句中填充条件,您可以在连接发生后将其应用于整个结果集。本质上,您将LEFT OUTER JOIN 变成INNER JOIN。相反,您希望该过滤器在连接之前发生在您的 entite 表中,因此子查询或仅将条件移动到 ON 子句就足够了。
  • @philipxy 不,不是这个问题。我知道我必须写一个简洁的问题,清楚。但就我而言,如果不设置上下文和表格,就不可能解释我的问题以及我想要得到的东西。对不起

标签: sql sql-server tsql left-join where-clause


【解决方案1】:

只需将let joined 表Entite 上的条件移动到联接的on 部分。否则,它成为一个强制条件,并过滤掉Entite中没有匹配的记录。

SELECT
            ProprietesCourantes.IdEntite                                                                    as IdEntite, 
            ProprietesCourantes.Libelle                                                                     as RaisonSociale,
            Entite.CodeEntite                                                                               as IdCMCIC,
            ProprietesCourantes.NomParent                                                                   as NomGN,
            Archive.NoteFinale                                                                              as Cotation,
            Archive.DateValiditeQuestionnaireDeSoutien                                                      as DateValiditeQuestionnaireDeSoutien,
            ProprietesCourantes.CodePays                                                                    as Pays,
            ProprietesCourantes.EstActif                                                                    as Statut,
            CAST(CASE WHEN Entite.CodeEntite = ProprietesCourantes.IdSocMere THEN 1 ELSE 0 END AS BIT)      as EstMaisonMere,
            ProprietesCourantes.IdCMCICParent                                                               as IdCMCICParent,
            ProprietesCourantesGN.CodeAlgo                                                                  as CodeAlgoParent    
    FROM ProprietesCourantes    
    LEFT JOIN Archive
        ON  Archive.IdEntite  = ProprietesCourantes.IdEntite 
        AND Archive.EstValide=1)
    LEFT JOIN Entite 
        ON  Entite.IdEntite = ProprietesCourantes.IdEntite 
        AND Entite.TypeEntite = 1 
    LEFT JOIN Entite as EntiteGN 
        ON  EntiteGN.CodeEntite = ProprietesCourantes.IdCMCICParent
    LEFT JOIN ProprietesCourantes as ProprietesCourantesGN 
        ON  ProprietesCourantesGN.IdEntite = EntiteGN.IdEntite
    WHERE ProprietesCourantes.Libelle LIKE '%'+'DELTA SERVICE'+'%' 

【讨论】:

  • 好吧,我明白了,但它总是让我两个字段都为 NULL,我必须找到一种方法来加入表才能获得 CotationDateValiditeQuestionnaireDeSoutien。也许我的问题不是很清楚? LEFT JOIN Archive ON Archive.IdEntite = ProprietesCourantes.IdEntite AND Archive.EstValide=1) 无法匹配
【解决方案2】:

要查看您的表的情况并不容易...存档表是否可能没有 IdEntite='165' 的行?这两个键的格式是否相同?您正在显示 IdEntite='165' 的输出,但 4 个示例表适用于 2 个不同的 IdEntite。您能否提供更多见解?

已编辑: 据我了解,您想通过 ProprietesCourantesArchive 的 Libelle 字段加入,但您的加入是基于 IdEntite?

如果是这样,使用中间表连接 ```...

Archive.NoteFinale                                   as Cotation,
Archive.DateValiditeQuestionnaireDeSoutien           as DateValiditeQuestionnaireDeSoutien,
...
LEFT JOIN EntiteArchive ON (EntiteArchive.Libelle = ProprietesCourantes.Libelle )
LEFT JOIN Archive ON (EntiteArchive.IdEntite = Archive.IdEntite)
...
```

【讨论】:

  • 是的,向您展示数据库关系并不容易。但是对于名为(Libelle 字段)“DELTA SERVICE AUTO”的同一对象,它在 ProprietesCourantes 表中的 IdEntite = '165' 和在存档表中的 IdEntite = '33'。
  • 它似乎工作得很好!这似乎是一个很好的答案:) 谢谢! 编辑如果我想通过 CodeEntite 字段加入,可以吗?
  • 我改变了这个,它也可以工作:LEFT JOIN EntiteArchive ON (EntiteArchive.CodeEntite = (SELECT CodeEntite FROM [dbo].Entite WHERE Entite.IdEntite = ProprietesCourantes.IdEntite)) LEFT JOIN Archive ON (EntiteArchive.IdEntite = Archive.IdEntite and Archive.EstValide=1)
【解决方案3】:

CodeEntite 可以用作连接吗?

JOIN [EntiteArchive] ON [Entite].[CodeEntite] =  [EntiteArchive].[CodeEntite] 
JOIN [Archive] ON [EntiteArchive].[IdEntite]  = [Archive].[IdEntite] 

【讨论】:

  • 是的,这就是我想要做的。我写了这个,但这不是一个好的语法,只是为了得到这个想法:LEFT JOIN Archive ON (SELECT CodeEntite FROM EntiteArchive WHERE IdEntite = Archive.IdEntite = SELECT CodeEntite FROM Entite WHERE IdEntite = ProprietesCourantes.IdEntite)
猜你喜欢
  • 1970-01-01
  • 2014-05-26
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 2013-05-13
  • 2012-04-05
  • 2011-01-22
  • 1970-01-01
相关资源
最近更新 更多