水晶报表的SQL查询产生重复的结果

时间:2018-07-16 14:11:53

标签: sql sql-server crystal-reports

我创建了3个表TstInvoice,TstProd,TstPersons并添加了一些数据:

INVOICE_NBR CLIENT_NR   VK_CONTACT
A10304      003145      AT  
A10305      000079      EA  
A10306      004458      AT  
A10307      003331      JDJ 

PROD_NR INVOICE_NBR
P29366  A10304
P29367  A10304
P29368  A10305
P29369  A10306
P29370  A10306
P29371  A10307

PERS_NR INITIALEN   STATUS  PERSOON
0001    AT          7       Alice Thompson           
0002    EA          1       Edgar Allen              
0003    JDJ         1       John Doe Joe             
0004    AT          1       Arthur Twins  

传递到水晶报表的参数是INVOICE_NBR。

在我的水晶报表上,我从数据库中放入了一些字段和一个sql表达式:

(
SELECT "TstPersons"."PERSOON" FROM "TstPersons"
WHERE "TstPersons"."INITIALEN" = "TstInvoice"."VK_CONTACT" AND "TstPersons"."STATUS" = 1
)

生成的完整查询:

 SELECT "TstInvoice"."INVOICE_NBR", "TstInvoice"."CLIENT_NR", "TstPersons"."STATUS", "TstPersons"."PERSOON", "TstProd"."PROD_NR", "TstProd"."INVOICE_NBR", (
SELECT "TstPersons"."PERSOON" FROM "TstPersons"
WHERE "TstPersons"."INITIALEN" = "TstInvoice"."VK_CONTACT" AND "TstPersons"."STATUS" = 1
)
 FROM   ("GCCTEST"."dbo"."TstInvoice" "TstInvoice" INNER JOIN "GCCTEST"."dbo"."TstProd" "TstProd" ON "TstInvoice"."INVOICE_NBR"="TstProd"."INVOICE_NBR") INNER JOIN "GCCTEST"."dbo"."TstPersons" "TstPersons" ON "TstInvoice"."VK_CONTACT"="TstPersons"."INITIALEN"
 WHERE  "TstInvoice"."INVOICE_NBR"='A10304'

结果如屏幕截图所示: result

您会看到TstPersons.PERSOON字段填充了Alice Thompson,而sql表达式字段填充了Arthur Twins。但是,我只想看一次prod_nr。通过该查询,尽管我只要求状态1,但由于两次输入“ AT”,因此会产生两次生产编号。我可以删除旧的条目,但我想知道是否可以这样。

*编辑* 我将状态= 1添加到“记录选择公式编辑器”中,这似乎可行。完全不需要sql表达式字段。不确定这是否是正确的方法。

所以现在看起来像这样:

 SELECT "TstInvoice"."INVOICE_NBR", "TstInvoice"."CLIENT_NR", "TstPersons"."STATUS", "TstPersons"."PERSOON", "TstProd"."PROD_NR", "TstProd"."INVOICE_NBR"
 FROM   ("GCCTEST"."dbo"."TstInvoice" "TstInvoice" INNER JOIN "GCCTEST"."dbo"."TstProd" "TstProd" ON "TstInvoice"."INVOICE_NBR"="TstProd"."INVOICE_NBR") INNER JOIN "GCCTEST"."dbo"."TstPersons" "TstPersons" ON "TstInvoice"."VK_CONTACT"="TstPersons"."INITIALEN"
 WHERE  "TstInvoice"."INVOICE_NBR"='A10304' AND "TstPersons"."STATUS"=1

1 个答案:

答案 0 :(得分:1)

由于在INITIALEN列中发现重复的值,因此查询中的联接非常弱。使用STATUS = 1条件不仅可以解决问题,还可以解决,因为如果您需要报告状态为1以外的发票,则需要修改报告的设计以允许您加入之所以起作用,是因为在发票上找不到STATUS值,无法进行正确的合并。

如果另一个联系人的姓名缩写和状态值与另一个姓名相同,那么您也有可能会完全解决此解决方法。

解决此问题的正确方法是通过具有唯一值的字段将TstInvoiceTstPersons连接起来。 PERS_NR列似乎是一个不错的选择。

这还需要重新设计TstInvoice表,以将PERS_NR列作为外键。

发票与人员之间更强的联接也可以消除选择语句中对该子查询的需要。这样可以将查询简化为以下内容:

SELECT "TstInvoice"."INVOICE_NBR", "TstInvoice"."CLIENT_NR", "TstPersons"."STATUS", "TstPersons"."PERSOON", "TstProd"."PROD_NR", "TstProd"."INVOICE_NBR" FROM "GCCTEST"."dbo"."TstInvoice" "TstInvoice" INNER JOIN "GCCTEST"."dbo"."TstProd" "TstProd" ON "TstInvoice"."INVOICE_NBR"="TstProd"."INVOICE_NBR" INNER JOIN "GCCTEST"."dbo"."TstPersons" "TstPersons" ON "TstInvoice"."PERS_NR"="TstPersons"."PERS_NR" WHERE "TstInvoice"."INVOICE_NBR"='A10304'