JPA/JPQL 및 최대 절전 모드를 사용하여 항목을 인용 할 수있는 엔티티가 몇 개 있습니다.JPQL 조인으로 결과를 두 배로 만드는 방법이 없습니다.
견적에는 많은 견적 항목이 있으며 각 항목에는 0 개 이상의 조정 사항이있을 수 있습니다. 각각의 조정은 할인 또는 할증료이며, 백분율 (즉, 항목의 가격 비율) 또는 금액 (즉, 고정 값)입니다.
저에게 가치를 줄 수있는 JPQL 쿼리를 작성하려고합니다. 주어진 지역 및 사용자 및 시간 기간에 대한 모든 견적을 인용 부호에 대한 각 견적 항목의 가격과 조정 값을 합산합니다. 나는 거의 일하고 있지만 그것이 옳지 않다.
String query = "select q.user, q.contact.parent.region, sum(case " +
" when a.type = :type_surcharge and a.amountType = :amount_type_percentage then (a.amount * qi.price) " +
" when a.type = :type_surcharge and a.amountType = :amount_type_amount then (a.amount) " +
" when a.type = :type_discount and a.amountType = :amount_type_percentage then (-1 * a.amount * qi.price) " +
" else (-1 * a.amount) end) + sum(qi.price) " +
" from " + Quote.class.getName() + " q " +
" left join q.quoteItems qi " +
" left join qi.adjustments a " +
" where q.date between :from and :to and q.contact.parent.region in :regions group by q.user, q.contact.parent.region";
문제는 견적 항목이 하나 이상의 조정이있는 경우, 그 항목이
사람이 쿼리에 수정을 도와 수
합 (qi.price) 계산에 여러 번 나타나는 것입니다 각 견적 항목을 합계에 한 번만 포함 시키려면? (sum(distinct qi.price)
작동하지 않습니다) 가능하면 단일 쿼리에서 수행 할 수 있기를 바래요.
편집 : 내가 생각했던 것보다 더 잘못되었습니다. 왼쪽 조인 (?)을 사용하고 있어도 조정하지 않고 따옴표가 있으면 합계 값에 대해 쿼리가 null을 반환합니다. 데이터가 올바른 경우는 다음과 같습니다. - 항목에 대해 0 또는 1 조정이 있습니다. - 지역/사용자/기간 필터를 통과하는 모든 따옴표에 하나 이상의 항목에 대한 조정이 있습니다.
엔티티 (간체)
@Entity
@DiscriminatorValue(AbstractCollateral.TYPE_QUOTE)
@Table(name="customer_quote", uniqueConstraints={@UniqueConstraint(name="quote_number_uk", columnNames={"number"})})
public class Quote extends AbstractCollateral<QuotedCarePack>
{
... other elements
@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval=true)
protected Set<QuotedCarePack> quoteItems;
}
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="collateral_type", discriminatorType=DiscriminatorType.STRING, length=10)
@Table(name="abstract_collateral")
public abstract class AbstractCollateral<T extends AbstractCollateralItem<?>> extends AbstractManagedData implements ContactInfo{
private static final long serialVersionUID = 1L;
public static final String TYPE_ORDER = "order";
public static final String TYPE_QUOTE = "quote";
@Column(name="collateral_type", insertable=true, updatable=false, length=10)
protected String collateralType;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="customer_contact_id", nullable=false)
protected CustomerContact contact;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="user_id", nullable=false)
protected User user;
/**
* The date the collateral was made (not the sent date, necessarily)
*/
@Column(name="creation_date", nullable=false)
@Temporal(TemporalType.TIMESTAMP)
protected Date date;
}
@Entity(name="quoted_care_pack")
public class QuotedCarePack extends AbstractCollateralItem<Quote> {
private static final long serialVersionUID = 1L;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="quote_id", nullable=false)
protected Quote parent;
@OneToMany(fetch=FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable
(
name="quoted_care_pack_adjustment",
joinColumns={ @JoinColumn(name="quoted_care_pack_id", referencedColumnName="id") },
inverseJoinColumns={ @JoinColumn(name="adjustment_id", referencedColumnName="id", unique=true) }
)
protected Set<Adjustment> adjustments;
}
@Entity(name="adjustment")
public class Adjustment extends AbstractManagedData {
private static final long serialVersionUID = 1L;
@Column(name="amount")
protected double amount;
@Column(name="reason", length=100)
protected String reason;
@Column(name="type")
@Enumerated(EnumType.STRING)
protected AdjustmentType type;
@Column(name="amount_type")
@Enumerated(EnumType.STRING)
protected AdjustmentAmountType amountType;
}
감사 크리스! 부끄러운 일이지만 한 가지 쿼리로 수행 할 수는 없지만 제대로 작동합니다. – fancyplants