crystal报表的SQL查询生成重复的结果

crystal报表的SQL查询生成重复的结果,sql,sql-server,crystal-reports,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 P

我创建了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  
传递到crystal报表的参数是发票编号

在crystal报告中,我从数据库中输入了一些字段和一个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'
结果如屏幕截图所示:

如您所见,TstPersons.PERSOON字段由Alice Thompson填充,sql表达式字段由Arthur Twins正确填充。然而,我只想看一次产品。通过这个查询,它会两次生成产品编号,因为“AT”有两个条目,尽管我只要求状态1。我可以删除旧条目,但我想知道这样是否可行

*edit*我将status=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

由于
INITIALEN
列中存在重复值,因此查询中的联接非常弱。使用
STATUS=1
标准不仅仅是一种解决方案,而是一种变通方法,因为如果您需要报告联系人状态不是1的发票,则需要修改报告的设计以允许加入工作,因为发票上找不到
STATUS
值以允许进行适当的加入

如果您有另一个联系人的姓名首字母和状态值与另一个联系人的姓名首字母和状态值相同,您也会面临工作完全崩溃的风险

解决此问题的正确方法是通过具有唯一值的字段将
TstInvoice
连接到
TstPersons
PERS\u NR
列似乎是一个很好的选择

这还需要重新设计
TstInvoice
表,将
PERS\u NR
列作为外键

发票和人员之间更紧密的连接也将消除选择语句中对子查询的需要。这会将查询简化为以下内容:

选择“TstInvoice”、“发票号”、“TstInvoice”、“客户号”、“TstPersons”、“状态”、“TstPersons”、“个人号”、“TstProd”、“产品号”、“TstProd”、“发票号”
从“GCCTEST”“dbo”“TstInvoice”“TstInvoice”
内部联接“GCCTEST”“dbo”“TstProd”“TstProd”
在“TstInvoice”上,“发票编号”=“TstProd”。“发票编号”
内部联接“GCCTEST”、“dbo”、“TstPersons”和“TstPersons”
在“TstInvoice”上,“PERS_NR”=“TstPersons”“PERS_NR”

其中“TstInvoice”。“INVOICE\u NBR”=“A10304”

是的,这就是我害怕的。重新设计桌子,但这可能是最好的方法。