2013-10-28 1 views
0

내가 다음 반환하는 HQL 쿼리를 작성하려고하지있어 반환HQL은 : 가입 여러 컬렉션 쿼리가 아무것도

그들의 propertyTags 내 inclusionTags
을 또는 내 propertyTags에있는 자신의 inclusionTags에를
및 해당 속성 태그는 내 제외 태그가 아니며
내 propertyTags는 제외 태그가 아닙니다.

는 여기에 지금까지있어 무엇 :

def thePropertyTags = this.propertyTags 
if(thePropertyTags == null || thePropertyTags.size() == 0) { 
    thePropertyTags = [ Tag.UNUSED_TAG ] 
} 

def theInclusions = this.inclusionTags 
if(theInclusions == null || theInclusions.size() == 0) { 
    theInclusions = [ Tag.UNUSED_TAG ] 
} 

def theExclusions = this.exclusionTags 
if(theExclusions == null || theExclusions.size() == 0) { 
    theExclusions = [ Tag.UNUSED_TAG ] 
} 

List<MyDomain> objects = MyDomain.executeQuery(""" 
    SELECT DISTINCT o 
    FROM MyDomain o 

    JOIN o.propertyTags as propertyTags 
    JOIN o.exclusionTags as exclusions 
    JOIN o.inclusionTags as inclusions 

    WHERE o.id != :id 
    AND o.isActive = true 

    AND (
     exclusions IS NULL 
     OR exclusions IS EMPTY 
     OR exclusions NOT in (:propertyTags) 
    ) 

    AND propertyTags NOT in (:exclusions) 

    AND (
     inclusions in (:propertyTags) 
     OR propertyTags in (:inclusions) 
    ) 

""", [id: id, inclusions: theInclusions, exclusions: theExclusions, propertyTags: thePropertyTags]) 

문제는 exclusionTags 반환 할 아무 것도 발생하지 않습니다 합류에 관계없이 포함/propertyTags 매칭이다. 모든 제외 조항을 제거해도 아무 것도 반환되지 않습니다. 반환 할 항목을 얻는 유일한 방법은 JOIN을 모두 제거하는 것입니다.

도메인 :

MyDomain { 
    boolean isActive = true 

    static hasMany = [propertyTags: Tag, inclusionTags: Tag, exclusionTags: Tag] 

    static constraints = { 
     propertyTags(nullable: false) 
     inclusionTags(nullable: false) 
     exclusionTags(nullable: false) 
    } 
} 

Tag { 
    private static final List<Integer> TAG_TYPES = [...] 

    String name 
    int type 
    String description 

    static constraints = { 
     name(unique: true, nullable: false, blank: false) 
     type(inList: [TAG_TYPES]) 

     description(nullable: true, blank: true) 
    } 
} 

업데이트 :

내가 지금 같은 LEFT JOIN에 흠도/제외를 변경했습니다,하지만 예외가에있는 경우가 여전히 레코드가 반환되는 검색어 :

List<MyDomain> objects = MyDomain.executeQuery(""" 
    SELECT DISTINCT o 
    FROM MyDomain o 

    JOIN o.propertyTags as propertyTags 
    LEFT JOIN o.exclusionTags as exclusions 
    LEFT JOIN o.inclusionTags as inclusions 

    WHERE o.id != :id 
    AND o.isActive = true 

    AND exclusions NOT in (:propertyTags) 
    AND propertyTags NOT in (:exclusions) 

    AND (
     inclusions in (:propertyTags) 
     OR propertyTags in (:inclusions) 
    ) 

""", [id: id, inclusions: theInclusions, exclusions: theExclusions, propertyTags: thePropertyTags]) 
+0

도메인 클래스는 어떻게 생겼습니까? – dmahapatro

+0

@dmahapatro가 도메인을 추가했습니다 – kz3

답변

0

처음 보는 문제는 그쪽으로 t 제외 태그에 대한 내부 조인을 수행하고 있습니다. 이렇게하면 제외 태그가있는 레코드 만 반환됩니다. 당신은뿐만 아니라

LEFT JOIN o.exclusionTags as exclusions 
LEFT JOIN o.inclusionTags as inclusions 

이 그럼 당신은 할 수 있어야 시도하는 것이 참여 왼쪽한다, 그래서 또한 더 포함 태그가없는 "MYDOMAIN"과 "그들의 propertyTags 내 inclusionTags에"만족 될 수있다 간단하게이 작업을 수행 :

AND (
    exclusions NOT in (:propertyTags) 
) 

편집 :. OK 내가 그것을 가지고 - 문제는 없습니다에 최대 절전 이것에 대해 이상한이다. 원래 응답을 게시하기 전에 모든 태그가 false가 허용된다는 것을 알지 못 했으므로 왼쪽 조인을 수행하는 것은 의미가 없습니다.

MyDomain.executeQuery("select distinct m from MyDomain m join m.propertyTags as pt join m.inclusionTags as it where m.id != :id and m.isActive = true and (pt in (:inclusionTags) or it in (:propertyTags)) and m not in (select m from MyDomain m join m.propertyTags as pt where pt in (:exclusionTags)) and m not in (select m from MyDomain m join m.exclusionTags as et where et in (:propertyTags))", [id: id, inclusionTags: theInclusions, propertyTags: thePropertyTags, exclusionTags: theExclusions]) 
+0

LEFT JOIN 예제로 질문을 업데이트했지만 쿼리에 제외가 포함되어 있으면 아무 것도 반환하지 않습니다. – kz3

+0

업데이트 된 답변보기 –

+0

도움을 주셔서 감사합니다. 실제로 동일한 솔루션을 알아 냈습니다. 오늘 일찍. 어쨌든, 현상금은 너의 것이다, 고마워! – kz3