2011-08-11 3 views
0

이 포털을 처음 사용합니다. 나는 해결해야 할 아주 간단한 문제가있다. 이것은 ANSI SQL과 관련이 있습니다. BIRT를 사용하여 보고서를 작성 중이며 여러 테이블에서 데이터를 가져옵니다. 나는 SQL이 어떻게 작동하는지 이해하지만 어쩌면 완전하지는 않을 것이다. 나는 몇 시간 동안 Google을 연구했고 관련 답변을 찾을 수 없었습니다.관계가 쿼리에서 중복 레코드를 생성합니다. DISTINCT가 작동하지 않으며 다른 솔루션을 사용할 수 있습니까?

내 문제는 코드의 관계 중 하나가 동일한 결과를 생성한다는 것입니다 (동일한 행이 복사 됨 - 복제 됨). 나는 그것을 해결할 결심 이었기 때문에 모든 유형의 조인을 사용할 수있었습니다. 이 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' 

나는 테스트 데이터의 너무 많이 없지만 나는 1 개 개의 행이 나는 DISTINCT 키워드를 사용하더라도 그래도 아래 쿼리의 결과로 두 번 복사됩니다 것을 알고있다. 나는 내 문제가 다소 구체적이고 일반적인 것이 아니라는 것을 알고있다. 누군가가 제안 할 해결책은 비슷한 문제를 가진 다른 사람들을 도울 수있다.

답변

1

몇 가지 테스트 데이터없이 문제를 해결할 수는 없지만 유용한 힌트가 있습니다.

기본적으로 DISTINCT는 쿼리에 버그를 숨기는 훌륭한 방법입니다. 기본 데이터에 합법적 인 중복이 포함되어 있다고 확신하는 경우에만 DISTINCT를 사용하십시오. 조인이 잘못되어 Cartesian 제품을 얻는 경우 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 

과 조인 다음에 구축.

+0

대단히. 데이터베이스의 경우 간단한 보고서 나 복잡한 쿼리를 디자인 할 때마다 항상 테이블의 구조를 연구하고 명확한 참조가 필요한 ERD를 작성하는 경향이 있습니다. 나는 'distinct by'대신에 duplicates를 건너 뛰기 위해 'group by'명령을 사용하는 누군가를 보았다. – techspeque

+0

Johann Strydom에 대한 귀하의 답변을 보았습니다. emediadetails.data에 추가 콘텐츠가있는 경우 테이블에 조인 기준과 일치하는 두 개의 행이 있음을 알 수 있습니다. 조인을 정제하여 검색 할 행을 지정하는 방법이 있습니까? 가장 중요한 방법은 "%
'이 아닌"Cplandata "를 추가하는 것이지만 더 좋은 방법이 있습니다."그룹화 기준 "을 사용하여이 작업을 수행하는 방법은 max (keyvalue1)를 선택한 다음 모든 그룹별로 그룹화하는 것입니다. 해당 열의 데이터가 합법적으로 복제되고 첫 번째 레코드가 원하는 경우에만 수행하십시오. –

0

결과가 정확한지 확인하십시오. 실제로 다른 값을 가진 열이 하나도 없는지 확인합니다.

+0

답장을 보내 주셔서 감사합니다. 정말 미안해. 단 하나의 차이점이 있습니다 : 필드 - CAST (VARCHAR (MAX)와 같은 emediadetails.data) 데이터는
태그가 다른 행에없는 한 행으로 구성됩니다. 문제는 이러한 행이 사실상 동일하다는 것입니다. 이 행의 반복을 제외하면됩니다. 값이 다르더라도 다른 필드가 같으면이 필드를 생략하면됩니다. 결과 중 하나를 생략하기 위해 '그룹화'를 사용할 수 있습니까? – techspeque

+0

@techspeque : "이 행은 사실상 같습니다." 당신은 의심 할 여지없이 "이 행은 다릅니다"라고 말하려고했습니다. 왜냐하면 그것들이 다르기 때문입니다. 선택한 열의 값이 다르면 서로 다를 것입니다. 그것들을 똑같이 만들고 싶다면 (정말 나쁜 생각처럼 들리지만) 쿼리에서 해당 열을 삭제하거나 데이터를 복사하여 두 행에서 동일하게 만드십시오. (다시 말하지만, 그것은 정말로 나쁜 생각처럼 들립니다.) –

+0

@Catcall, 나는 그들이 똑같다 고 말했다. 문제는 데이터가 HTML 코드였습니다. 그리고 중간에있는 1200 자의 길이에서
태그가 추가되었고 나는 그것을 발견 할 수 없었습니다. 또한 데이터를 미리 볼 때 형식이 지정된 HTML 페이지로 표시되어 쉽지 않았습니다. 노력해 주셔서 대단히 감사합니다. – techspeque