【问题标题】:SQL LEFT JOIN and GROUP BYSQL LEFT JOIN 和 GROUP BY
【发布时间】:2016-04-11 21:37:41
【问题描述】:

我有一个表 T_DONNE,它只是导入数据的类型。 Noid = ID Libelle = 标签

NOID    LIBELLE
1       WEB
2       FTP

客户:

CODE_CL   RS_NOM  VILLE      TYPE_CLIENT
85000     test    La roche   1
85001     azerty  Nantes     2
85002     qsdfg   Nantes     1

LETTRE_VOIT_FINAL:就像客户命令的物品

  NOID  CODE_CLIENT RS_NOM   VILLE_EXP  FACTURATION   DATE_CLOTUR_REEL
  1     85000       test     La roche   2             2016-01-07 15:02:59
  2     85000       test     La roche   2             2016-01-07 15:03:59
  3     85001       azerty   Nantes     2             2016-01-07 15:04:59

我想要的是:

CODE_CLIENT  RS_NOM    VILLE_EXP  LIBELLE  TOTAL
85000        test      La roche   WEB      2
85001        azerty    Nantes     FTP      1
85002        qsdfg     Nantes     WEB      0

和 sql:

SELECT           
       LETTRE_VOIT_FINAL.CODE_CLIENT
      ,LETTRE_VOIT_FINAL.RS_NOM
      ,LETTRE_VOIT_FINAL.VILLE_EXP         
      ,T_DONNE.LIBELLE
      ,count (LETTRE_VOIT_FINAL.NOID) as TOTAL    
FROM LETTRE_VOIT_FINAL 
LEFT OUTER JOIN CLIENT ON CLIENT.CODE_CL  = LETTRE_VOIT_FINAL.CODE_CLIENT  
LEFT JOIN T_DONNE ON T_DONNE.NOID = CLIENT.TYPE_CLIENT

WHERE DATE_CLOTUR_REEL BETWEEN @DateDeb AND @DateFin
and FACTURATION = @FACTURATION
and STATUT_LV = 2  
group by CODE_CLIENT,VILLE_EXP,RS_NOM,LIBELLE

它并不完全有效。它只显示:

  CODE_CLIENT  RS_NOM    VILLE_EXP   LIBELLE  TOTAL
    85000        test      La roche   WEB      2
    85001        azerty    Nantes     FTP      1

我认为它不起作用,因为 NULL 值和计数功能。

我想列出所有客户并计算她/他命令的项目。 我的语法只显示有命令的客户端,我错过了在我的示例中没有命令的客户端是客户端 85002

我也倒过来了,结果还是一样:

SELECT 
    count (LETTRE_VOIT_FINAL.NOID) as TOTLV
    ,CODE_CL
    ,VILLE
    ,[RS_NOM]
    ,LIBELLE
FROM CLIENT 
LEFT JOIN LETTRE_VOIT_FINAL ON CLIENT.CODE_CL  = LETTRE_VOIT_FINAL.CODE_CLIENT  
LEFT JOIN T_DONNE ON T_DONNE.NOID = CLIENT.TYPE_CLIENT   

WHERE DATE_CLOTUR_REEL BETWEEN @DateDeb AND @DateFin
and FACTURATION = @FACTURATION
and STATUT_LV = 2  

group by CODE_CL,VILLE,RS_NOM,LIBELLE

@DateDeb 日期时间,@DateFin 日期时间,@FACTURATION int',@DateDeb='2016-01-07 12:00:00',@DateFin='2016-01-07 23:59:59',@FACTURATION =2

【问题讨论】:

  • 您的查询和您的数据不一致。您的查询中有未提及的列作为任何表的一部分。在任何情况下,您都希望将条件从 WHERE 移动到适当的 ON 子句。
  • 对不起,我已经写好了
  • 限定列名,table_name.column_name,这样我们就可以知道一个列属于哪个表。
  • 请在所有列上使用 table.column 表示法,如果我们不知道该列来自哪个表,我们将无法帮助您
  • @Soft8Stev 。 . . where 非常重要,因为它将外连接变为内连接。部分或全部条件需要移到on 子句中。

标签: sql sql-server sql-server-2008 join group-by


【解决方案1】:

你不需要那个派生表来回答

SELECT CLIENT.CODE_CL
      ,CLIENT.RS_NOM
      ,CLIENT.VILLE  
      ,T_DONNE.LIBELLE
      ,count (LETTRE_VOIT_FINAL.NOID) as TOTLV    
 FROM CLIENT
 LEFT JOIN LETTRE_VOIT_FINAL
        on LETTRE_VOIT_FINAL.CODE_CLIENT = CLIENT.CODE_CL 
       and LETTRE_VOIT_FINAL.DATE_CLOTUR_REEL BETWEEN @DateDeb AND @DateFin
       and LETTRE_VOIT_FINAL.FACTURATION = @FACTURATION
       and LETTRE_VOIT_FINAL.STATUT_LV = 2    
 LEFT JOIN T_DONNE 
        ON T_DONNE.NOID = CLIENT.TYPE_CLIENT
where CLIENT.TYPE_CLIENT != 0
group by CLIENT.CODE_CL, CLIENT.VILLE, CLIENT.RS_NOM,LIBELLE

【讨论】:

    【解决方案2】:

    我明白了,感谢您的所有意见。

      SELECT           
           CLIENT.CODE_CL
          ,CLIENT.RS_NOM
          ,CLIENT.VILLE  
          ,T_DONNE.LIBELLE
          ,count (LETTRE_VOIT_FINAL.NOID) as TOTLV    
      FROM CLIENT
     LEFT OUTER JOIN 
      (
    
      SELECT *
            FROM   LETTRE_VOIT_FINAL 
            WHERE DATE_CLOTUR_REEL BETWEEN @DateDeb AND @DateFin
            and FACTURATION = @FACTURATION
            and STATUT_LV = 2 
    
            )
       LETTRE_VOIT_FINAL ON  CLIENT.CODE_CL  = LETTRE_VOIT_FINAL.CODE_CLIENT  
      LEFT JOIN T_DONNE ON T_DONNE.NOID = CLIENT.TYPE_CLIENT
    
    where type_client != 0
    
       group by CLIENT.CODE_CL,CLIENT.VILLE,CLIENT.RS_NOM,LIBELLE
    

    【讨论】:

      【解决方案3】:

      您正在引用LETTRE_VOIT_FINAL,我认为您不想这样做。现在您已经添加了更多信息,我改用子查询重写了查询。您也可以使用 join 子句来做到这一点。无论如何,您不能对整个查询执行此操作。此查询生成您尝试创建的表

        Select client.code_cl
        , client.rs_nom
        , client.ville
        , t_donne.libelle
        , COUNT(l.noid) As total
        From client
        Inner join t_donne on t_donne.noid = client.type_client
        Left outer join (
            Select noid, code_client
            From lettre_voit_final 
            Where facturation = @facturation 
            and date_clotur_reel between @DateDeb and @DateEnd
            and status_lv = 2
        ) as l on l.code_client = client.code_cl
        group by client.code_cl
        , client.rs_nom
        , client.ville
        , t_donne.libelle
      

      首先将客户端表与标签值连接起来,这将为您提供:

      85000   test    La roche    WEB
      85001   azerty  Nantes  FTP
      85002   qsdfg   Nantes  WEB
      

      然后left outer join 用于包含所有这些值以及lettre_voit_final 表的子选定行中具有这些值的行数,从而为您提供:

      85000   test    La roche    WEB 2
      85001   azerty  Nantes  FTP 1
      85002   qsdfg   Nantes  WEB 0
      

      【讨论】:

      • 几乎...当我添加我的 where 子句时它不起作用...where DATE_CLOTUR_REEL BETWEEN @DateDeb AND @DateFin and FACTURATION = @FACTURATION and STATUT_LV = 2
      • @soft 这些列在哪个表中?
      • 在 LETTRE_VOIT_FINAL 中有
      【解决方案4】:

      从您的预期结果来看,您的值似乎来自 Client 表,但您的查询(和列名)显示您正试图从 Lettre_Voit_Final 表中获取它们。我认为这是你最大的问题。通过从 Client 表开始,您可以加入到该表 - LEFT OUTER JOIN 以确保您仍然获得 Client 表中的所有行,即使该行的其他表中不存在任何内容。

      SELECT
          C.code_client,
          C.rs_nom,
          C.ville,
          D.libelle,
          COUNT(*)
      FROM
          Client C
      INNER JOIN T_Donne D ON D.noid = C.type_client
      LEFT OUTER JOIN Lettre_Voit_Final LVF ON LVF.code_client = C.code_cl
      GROUP BY
          C.code_client,
          C.rs_nom,
          C.ville,
          D.libelle
      

      其他一些注意事项...

      您的列名似乎不一致(例如,code_client 与 code_cl)。这确实会减慢开发速度并导致其他编码错误。

      对于 ville 与 ville_exp,您可能有一些重复的数据(尽管我不确定)。也许其中一个是“默认”值,另一个是实际值或其他东西,并且在您的数据库中有意义,但只是需要注意的其他一些事情。

      【讨论】:

        【解决方案5】:

        您的查询流程 LETTRE_VOIT_FINAL => CLIENT => T_DONNE

        但是您在表 CLIENT 中使用无法连接的左连接记录(行)(即 - 没有连接子句规定的相应键)将不会被带到结果集中。将其更改为完全联接/右联接或更改表联接的顺序

        SELECT 
              count (LETTRE_VOIT_FINAL.NOID as TOTLV
        
              ,[CODE_CLIENT]
              ,VILLE_EXP
              ,[RS_NOM]
              ,LIBELLE
          FROM [LETTRE_VOIT_FINAL] 
          FULL OUTER JOIN CLIENT ON CLIENT.CODE_CL  = LETTRE_VOIT_FINAL.CODE_CLIENT  
          FULL OUTER T_DONNE ON T_DONNE.NOID = CLIENT.TYPE_CLIENT
          where 
         DATE_CLOTUR_REEL BETWEEN @DateDeb AND @DateFin
          and FACTURATION = @FACTURATION
           and STATUT_LV = 2  
           group by CODE_CLIENT,VILLE_EXP,RS_NOM,LIBELLE
        

        【讨论】:

        • 我得到了与我的语法 SQL 相同的结果
        • 请再试一次 - 现在两个连接都已完全退出
        猜你喜欢
        • 1970-01-01
        • 2021-01-30
        • 2021-11-06
        • 2020-05-17
        • 1970-01-01
        • 1970-01-01
        • 2020-03-19
        • 1970-01-01
        • 2015-08-21
        相关资源
        最近更新 更多