关系在查询时产生重复记录,DISTINCT 不起作用,还有其他可用的解决方案吗?

发布于 2024-11-29 07:37:17 字数 2372 浏览 12 评论 0原文

我是这个门户的新手。我有一个非常简单的问题需要解决。它与 ANSI SQL 有关。我正在使用 BIRT 编写报告,并从多个表中获取数据。我了解 SQL 连接是如何工作的,但可能不完全。我在谷歌上研究了几个小时,但找不到相关答案。

我的问题是代码中的关系之一产生重复的结果(复制同一行 - 重复)。我决心解决这个问题,所以我使用了所有可用的连接类型。其中一些 SQL 已经生成。我将在下面发布我的代码。我知道解决我的问题的方法之一是使用“DISTINCT”关键字。我已经使用过它并不能解决我的问题。

任何人都可以提出任何解决方案吗?

示例代码:

SELECT DISTINCT
   partmaster.partdesc,
   partmaster.uom,
   traders.name AS tradername,
   worksorders.id AS worksorderno,
   worksorders.partid,
   worksorders.quantity,
   worksorders.duedate,
   worksorders.traderid,
   worksorders.orderid,
   routingoperations.partid,
   routingoperations.methodid,
   routingoperations.operationnumber,
   routingoperations.workcentreid,
   routingoperations.settime,
   routingoperations.runtime,
   routingoperations.perquantity,
   routingoperations.description,
   routingoperations.alternativeoperation,
   routingoperations.alternativeoperationpreference,
   machines.macdesc,
   machines.msection,
   allpartmaster.partnum,
   allpartmaster.nbq,
   allpartmaster.partdesc,
   routingoperationtools.toolid,
   tools.tooldesc,
   CAST (emediadetails.data as VARCHAR(MAX)) AS cplandata
FROM worksorders
INNER JOIN partmaster ON worksorders.partid = partmaster.partnum
INNER JOIN traders traders ON worksorders.traderid = traders.id
INNER JOIN routingoperations routingoperations ON worksorders.partid = routingoperations.partid  
       AND worksorders.routingmethod = routingoperations.methodid
INNER JOIN allpartmaster allpartmaster ON routingoperations.partid = allpartmaster.partnum 
LEFT OUTER JOIN machines machines ON routingoperations.workcentreid = machines.macid
LEFT OUTER JOIN routingoperationtools routingoperationtools ON routingoperationtools.partid = routingoperations.partid 
           AND routingoperationtools.routingmethod = routingoperations.methodid 
           AND routingoperationtools.operationnumber = routingoperations.operationnumber     
LEFT OUTER JOIN tools tools ON tools.toolid = routingoperationtools.toolid 
LEFT OUTER JOIN emediadetails ON emediadetails.keyvalue1 = worksorders.id 
            AND emediadetails.keyvalue2 = routingoperations.operationnumber 
            AND emediadetails.emediaid = 'worksorderoperation' 

我没有太多的测试数据,但我知道即使我使用了 DISTINCT 关键字,一行也会作为下面查询的结果被复制两次。我知道我的问题相当具体,而不是普遍的,但有人提出的解决方案可能会帮助其他人解决类似的问题。

I am new to this portal. I have a very simple problem to be solved. It is related to the ANSI SQL. I am writing a reports using BIRT and I am fetching the data from several tables. I understand how the SQL joins work but maybe not fully. I researched google for hours and I could not find relevant answer.

My problem is that one of the relationships in the code produce a duplicate result (the same row is copied - duplicated). I was so determined to solve it I used every type of join available. Some of this SQL was produced already. I shall post my code below. I know that one of the solutions to my problem is use of the 'DISTINCT' keyword. I have used it and it does not solve my problem.

Can anyone propose any solution to that?

Sample code:

SELECT DISTINCT
   partmaster.partdesc,
   partmaster.uom,
   traders.name AS tradername,
   worksorders.id AS worksorderno,
   worksorders.partid,
   worksorders.quantity,
   worksorders.duedate,
   worksorders.traderid,
   worksorders.orderid,
   routingoperations.partid,
   routingoperations.methodid,
   routingoperations.operationnumber,
   routingoperations.workcentreid,
   routingoperations.settime,
   routingoperations.runtime,
   routingoperations.perquantity,
   routingoperations.description,
   routingoperations.alternativeoperation,
   routingoperations.alternativeoperationpreference,
   machines.macdesc,
   machines.msection,
   allpartmaster.partnum,
   allpartmaster.nbq,
   allpartmaster.partdesc,
   routingoperationtools.toolid,
   tools.tooldesc,
   CAST (emediadetails.data as VARCHAR(MAX)) AS cplandata
FROM worksorders
INNER JOIN partmaster ON worksorders.partid = partmaster.partnum
INNER JOIN traders traders ON worksorders.traderid = traders.id
INNER JOIN routingoperations routingoperations ON worksorders.partid = routingoperations.partid  
       AND worksorders.routingmethod = routingoperations.methodid
INNER JOIN allpartmaster allpartmaster ON routingoperations.partid = allpartmaster.partnum 
LEFT OUTER JOIN machines machines ON routingoperations.workcentreid = machines.macid
LEFT OUTER JOIN routingoperationtools routingoperationtools ON routingoperationtools.partid = routingoperations.partid 
           AND routingoperationtools.routingmethod = routingoperations.methodid 
           AND routingoperationtools.operationnumber = routingoperations.operationnumber     
LEFT OUTER JOIN tools tools ON tools.toolid = routingoperationtools.toolid 
LEFT OUTER JOIN emediadetails ON emediadetails.keyvalue1 = worksorders.id 
            AND emediadetails.keyvalue2 = routingoperations.operationnumber 
            AND emediadetails.emediaid = 'worksorderoperation' 

I do not have too much of the test data but I know that one row is copied twice as the result of the query below even tho I used DISTINCT keyword. I know that my problem is rather specific and not general but the solution that someone will propose may help others with the similar problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

岁吢 2024-12-06 07:37:17

如果没有一些测试数据,我无法为您解决问题,但我有一些有用的提示。

原则上,您应该非常小心 DISTINCT - 它是隐藏查询中错误的好方法。仅当您确信基础数据包含合法的重复项时才使用 DISTINCT。如果您的连接错误,并且您得到的是笛卡尔积,您可以使用 DISTINCT 从结果中删除重复项 - 但这并不能阻止笛卡尔积的生成。您将得到非常差的性能,并且可能会得到不正确的数据。

其次,我非常确定 DISTINCT 可以正常工作 - 您几乎肯定不会得到重复项,但可能很难发现两行之间的差异。例如,文本列中的前导或尾随空格可能是罪魁祸首。

最后,为了解决这个问题,我建议通过连接构建查询,并查看在哪里获得重复项 - 这就是应归咎的连接。

因此,从: 开始

SELECT 

                    traders.name AS tradername,
                    worksorders.id AS worksorderno,
                    worksorders.partid,
                    worksorders.quantity,
                    worksorders.duedate,
                    worksorders.traderid,
                    worksorders.orderid
                FROM worksorders
                    INNER JOIN traders traders ON
                        worksorders.traderid = traders.id

并构建到下一个连接。

I can't solve your problem for you without some test data, but I have some helpful hints.

In principle, you should be really careful with DISTINCT - its a great way of hiding bugs in your query. Only use DISTINCT if you are confident that the underlying data contains legitimate duplicates. If your joins are wrong, and you're getting a cartesian product, you can remove the duplicates from the results with DISTINCT - but that doesn't stop the cartesian product being generated. You'll get very poor performance, and possibly incorrect data.

Secondly, I am pretty sure that DISTINCT works properly - you are almost certainly not getting duplicates, but it may be hard to spot the difference between two rows. Leading or trailing spaces in text columns, for instance could be to blame.

Finally, to work through this problem, I'd recommend building the query up join by join, and seeing where you get the duplicate - that's the join that's to blame.

So, start with:

SELECT 

                    traders.name AS tradername,
                    worksorders.id AS worksorderno,
                    worksorders.partid,
                    worksorders.quantity,
                    worksorders.duedate,
                    worksorders.traderid,
                    worksorders.orderid
                FROM worksorders
                    INNER JOIN traders traders ON
                        worksorders.traderid = traders.id

and build up to the next join.

空心空情空意 2024-12-06 07:37:17

您确定结果完全重复吗?确保没有一列实际上具有不同的值。

Are you sure the results are exact duplicates? Makes sure there isn't one column that actually has a different value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文