3

Spring Data と QueryDSL 3.2.4 を使用しており、QueryDSL のネイティブ SQL API を使用して次の SQL クエリを実装したいと考えています。

WITH ORDER_GROUP AS (   -- TODO have to merge this subquery into the main query
    SELECT 
        ordergroup
       ,count(ID) AS nofOrdersPerGroup 
       ,MIN(priority) as minPriority
       ,MIN(requesteddeliverytime) as minRequestedDeliveryTime
       ,MIN(creationtime) as minCreationTime
      FROM ORDERHEADER hh
     group by orderGroup      
),
ALL_ORDERS AS (   -- TODO have to merge this subquery into the main query
    SELECT h.ordercode
      , h.ordergroup
      , h.priority
      , h.requesteddeliverytime
      , h.creationtime
      , h.statecode
      , (SELECT COUNT(ID)
           FROM orderposition p
          WHERE p.orderheaderid = h.ID
        ) AS nof_positions_per_order
      , CASE
            WHEN h.ordergroup IS NOT NULL
            THEN g.nofOrdersPerGroup
            ELSE 1
        END AS nof_orders_per_group
      , CASE
            WHEN h.ordergroup IS NOT NULL
            THEN g.minPriority
            ELSE h.priority
        END AS most_important_prio
      , CASE
            WHEN h.ordergroup IS NOT NULL
            THEN g.minRequestedDeliveryTime
            ELSE h.requesteddeliverytime
        END AS earliest_del_time
      , CASE
            WHEN h.ordergroup IS NOT NULL
            THEN g.minCreationTime
            ELSE h.creationtime
        END AS earliest_cre_time
       FROM ORDERHEADER h left outer join ORDER_GROUP g on h.ordergroup = g.ordergroup
      WHERE 1=1  -- TODO have to add filter clauses here
)
 SELECT ordercode
  , ordergroup
  , priority
  , requesteddeliverytime
  , creationtime
  , statecode
  , nof_positions_per_order
  , nof_orders_per_group
  , most_important_prio
  , earliest_del_time
  , earliest_cre_time
   FROM ALL_ORDERS
ORDER BY most_important_prio
  , earliest_del_time
  , earliest_cre_time
  , priority
  , requesteddeliverytime
  , creationtime;

結合は FK 列ではなく、サブクエリ ORDER_GROUP の任意の属性です。このサブクエリは、後で並べ替えに使用するために、OrderHeader の最小/最大値を集計します。

クエリの種類は次のとおりです。

package com.stoecklin.wms.entity;

import static com.mysema.query.types.PathMetadataFactory.*;

import com.mysema.query.types.path.*;

import com.mysema.query.types.PathMetadata;
import javax.annotation.Generated;
import com.mysema.query.types.Path;
import com.mysema.query.types.path.PathInits;


/**
 * QOrderHeader is a Querydsl query type for OrderHeader
 */
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QOrderHeader extends EntityPathBase<OrderHeader> {

    private static final long serialVersionUID = 2006939562;
    public static final QOrderHeader orderHeader = new QOrderHeader("orderHeader");
    public final com.stoecklin.utility.database.QBaseEntity _super = new com.stoecklin.utility.database.QBaseEntity(this);
    public final DateTimePath<java.util.Date> actualDeliveryTime = createDateTime("actualDeliveryTime", java.util.Date.class);
    public final StringPath creationMode = createString("creationMode");
    //inherited
    public final DateTimePath<java.util.Date> creationTime = _super.creationTime;
    public final StringPath customerCode = createString("customerCode");
    public final StringPath customerOrderCode = createString("customerOrderCode");
    public final StringPath deliveryCode = createString("deliveryCode");
    public final StringPath deliveryNote = createString("deliveryNote");
    public final StringPath headerText = createString("headerText");
    public final NumberPath<Integer> hostId = createNumber("hostId", Integer.class);
    public final NumberPath<Long> id = createNumber("id", Long.class);
    //inherited
    public final DateTimePath<java.util.Date> lastUpdateTime = _super.lastUpdateTime;
    public final StringPath orderCode = createString("orderCode");
    public final StringPath orderGroup = createString("orderGroup");
    public final ListPath<OrderPosition, QOrderPosition> orderPositions = this.<OrderPosition, QOrderPosition>createList("orderPositions", OrderPosition.class, QOrderPosition.class, PathInits.DIRECT2);
    public final StringPath orderTypeCode = createString("orderTypeCode");
    public final StringPath priority = createString("priority");
    public final DateTimePath<java.util.Date> requestedDeliveryTime = createDateTime("requestedDeliveryTime", java.util.Date.class);
    public final StringPath setupType = createString("setupType");
    public final StringPath shippingMode = createString("shippingMode");
    public final StringPath stagingArea = createString("stagingArea");
    public final EnumPath<com.stoecklin.wms.enums.OrderHeaderState> stateCode = createEnum("stateCode", com.stoecklin.wms.enums.OrderHeaderState.class);
    public final StringPath stateReason = createString("stateReason");
    public final DateTimePath<java.util.Date> stateTime = createDateTime("stateTime", java.util.Date.class);
    //inherited
    public final NumberPath<Long> version = _super.version;

    public QOrderHeader(String variable) {
        super(OrderHeader.class, forVariable(variable));
    }

    public QOrderHeader(Path<? extends OrderHeader> path) {
        super(path.getType(), path.getMetadata());
    }

    public QOrderHeader(PathMetadata<?> metadata) {
        super(OrderHeader.class, metadata);
    }

}

package com.stoecklin.wms.entity;

import static com.mysema.query.types.PathMetadataFactory.*;

import com.mysema.query.types.path.*;

import com.mysema.query.types.PathMetadata;
import javax.annotation.Generated;
import com.mysema.query.types.Path;
import com.mysema.query.types.path.PathInits;


/**
 * QOrderPosition is a Querydsl query type for OrderPosition
 */
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QOrderPosition extends EntityPathBase<OrderPosition> {

    private static final long serialVersionUID = 2091670278;
    private static final PathInits INITS = PathInits.DIRECT2;
    public static final QOrderPosition orderPosition = new QOrderPosition("orderPosition");
    public final com.stoecklin.utility.database.QBaseEntity _super = new com.stoecklin.utility.database.QBaseEntity(this);
    public final StringPath articleCode = createString("articleCode");
    //inherited
    public final DateTimePath<java.util.Date> creationTime = _super.creationTime;
    public final NumberPath<Integer> customerOrderPos = createNumber("customerOrderPos", Integer.class);
    public final NumberPath<Float> deliveredQuantity = createNumber("deliveredQuantity", Float.class);
    public final StringPath fromWarehouseCode = createString("fromWarehouseCode");
    public final StringPath hostData = createString("hostData");
    public final StringPath hostRef = createString("hostRef");
    public final NumberPath<Long> id = createNumber("id", Long.class);
    //inherited
    public final DateTimePath<java.util.Date> lastUpdateTime = _super.lastUpdateTime;
    public final StringPath lotCode = createString("lotCode");
    public final NumberPath<Float> missingQuantity = createNumber("missingQuantity", Float.class);
    public final QOrderHeader orderHeader;
    public final NumberPath<Integer> orderPos = createNumber("orderPos", Integer.class);
    public final StringPath ownerCode = createString("ownerCode");
    public final StringPath posText = createString("posText");
    public final NumberPath<Float> requestedQuantity = createNumber("requestedQuantity", Float.class);
    public final EnumPath<com.stoecklin.wms.enums.OrderPositionState> stateCode = createEnum("stateCode", com.stoecklin.wms.enums.OrderPositionState.class);
    public final StringPath stateReason = createString("stateReason");
    public final DateTimePath<java.util.Date> stateTime = createDateTime("stateTime", java.util.Date.class);
    public final StringPath toBePicked = createString("toBePicked");
    public final StringPath toLocation = createString("toLocation");
    //inherited
    public final NumberPath<Long> version = _super.version;

    public QOrderPosition(String variable) {
        this(OrderPosition.class, forVariable(variable), INITS);
    }

    public QOrderPosition(Path<? extends OrderPosition> path) {
        this(path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT);
    }

    public QOrderPosition(PathMetadata<?> metadata) {
        this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT);
    }

    public QOrderPosition(PathMetadata<?> metadata, PathInits inits) {
        this(OrderPosition.class, metadata, inits);
    }

    public QOrderPosition(Class<? extends OrderPosition> type, PathMetadata<?> metadata, PathInits inits) {
        super(type, metadata, inits);
        this.orderHeader = inits.isInitialized("orderHeader") ? new QOrderHeader(forProperty("orderHeader")) : null;
    }

}

今質問:

  1. ALL_ORDERS サブクエリの最後で結合を行うにはどうすればよいですか? 私はすでに次のことを試しました:

    QOrderHeader orderHeader = QOrderHeader.orderHeader;
    QOrderHeader orderHeaderGroup = new QOrderHeader("orderHeaderGroup");
    QOrderPosition orderPosition = QOrderPosition.orderPosition;
    
    List<Tuple> tuples = query.from(orderHeader)
            .leftJoin(orderHeader, orderHeaderGroup).on(orderHeader.orderGroup.eq(orderHeaderGroup.orderGroup))
            .list(
                    orderHeader.orderGroup,
                    orderHeader.id
                  );
    

しかし、一致するメソッド leftJoin が利用できないため、これもコンパイルされません。結合は FK 列ではなく、任意の属性です。サブクエリ ORDER_GROUP

  1. nof_orders_per_group (SELECT リストの 7 番目の項目) を計算する相関サブクエリはどのように実装されていますか? (私はこれを行う方法がわかりません:-))

上部に表示されている SQL は、効率を高めるために多少最適化されています。そのため、サブクエリがあちこちにあるため、ネイティブ SQL を使用することにしました。

どんな助けでも大歓迎です。

4

1 に答える 1