在连接表时显示空值

时间:2015-05-21 04:21:58

标签: mysql sql

下面是我的查询

 select C.cName,DATE_FORMAT(CT.dTransDate,'%d-%M-%Y') as dTransDate,  
  (c.nOpBalance+IFNULL(CT.nAmount,0)) AS DrAMount,IFNULL(CTR.nAmount,0) AS 
 CrAMount,((c.nOpBalance+IFNULL(CT.nAmount,0))-IFNULL(CTR.nAmount,0)) AS     
Balance,CT.cTransRefType,CT.cRemarks,cinfo.cCompanyName,cinfo.caddress1,cinfo.cP
     honeOffice,cinfo.cMobileNo,cinfo.cEmailID,cinfo.cWebsite from  Customer    
   C  LEFT JOIN Client_Transaction CT ON CT.nClientPk = C.nCustomerPk AND 
  CT.cTransRefType='PAYMENT' AND CT.cClientType='CUSTOMER' AND CT.dTransDate    
 between '' AND ''  LEFT JOIN Client_Transaction CTR ON CTR.nClientPk = 
   C.nCustomerPk AND CTR.cTransRefType='RECEIPT' AND 
   CTR.cClientType='CUSTOMER' AND CTR.dTransDate between '2015-05-01' AND 
  '2015-05-29'   LEFT JOIN companyinfo cinfo ON cinfo.cCompanyName like
 '%Fal%' Where C.nCustomerPk = 4   Order By dTransDate

它显示所有值,但 dTransDate cTransRefType cRemarks ,显示为空。

1 个答案:

答案 0 :(得分:1)

一件显而易见的事情突然出现在我们身上:

  CT.dTransDate BETWEEN '' AND '' 
                        ^^     ^^

另一件让我们感到震惊的事情是,CT之间的行和CTR之间的行之间存在半笛卡尔联接。如果从给定客户的CT返回5行,并且从CTR返回5行,那么将产生总共5 * 5 = 25行。这并不像你真正想要的结果集。

此外,如果从cinfo返回多行,那么这也将导致另一个半笛卡尔联接。如果从cinfo返回两行,则结果集中的总数将加倍。在SQL中执行此操作是有效的,但这是一种不寻常的模式。

balance的计算也很奇怪。对于每一行,从期初余额中添加/减去nAmount。在下一行,同样的事情,在原始的开放平衡。这样做没有什么无效的SQL,但返回的结果似乎很奇怪。 (您似乎更有可能希望在每笔交易中显示运行余额。)

我们跳出来的另一件事是你用DATE的字符串表示来排序行,以日为主要部分。 (只要所有行在同一年和月份都有日期值,这可能会起作用,但我们不会对DATE值或规范字符串表示进行排序似乎很奇怪。

我强烈怀疑你想要运行一个更像这样的查询。 (这不会进行"运行余额"计算。它会将'PAYMENT''RECEIPT'行作为单独的行返回,而不会产生半笛卡尔结果。

 SELECT c.cName
      , DATE_FORMAT(t.dTransDate,'%d-%M-%Y') AS dTransDate
      , C.nOpBalance
      , IF(t.cTransRefType='PAYMENT',IFNULL(t.nAmount,0),0) AS DrAMount
      , IF(t.cTransRefType='RECEIPT',IFNULL(t.nAmount,0),0) AS CrAMount
      , t.cTransRefType
      , t.cRemarks
      , ci.*
   FROM Customer c
   LEFT
   JOIN Client_Transaction t
     ON t.nClientPk      = c.nCustomerPk
    AND t.cClientType    = 'CUSTOMER'
    AND t.dTransDate    >= '2015-05-01'
    AND t.dTransDate    <= '2015-05-29'
    AND t.cTransRefType IN ('PAYMENT','RECEIPT')
  CROSS
   JOIN ( SELECT cinfo.cCompanyName
               , cinfo.caddress1
               , cinfo.cPhoneOffice
               , cinfo.cMobileNo
               , cinfo.cEmailID
               , cinfo.cWebsite
            FROM companyinfo cinfo 
           WHERE cinfo.cCompanyName LIKE '%Fal%'
           ORDER BY cinfo.cCompanyName
           LIMIT 1
        ) ci
  WHERE c.nCustomerPk = 4 
  ORDER BY t.dTransDate, t.cTransRefTpye, t.id