2

我尝试将此查询映射到 JPA 和 Join、Subqueries 和其他对我来说非常重要。也许你可以帮助我。这是我的查询:

SELECT customers.*
FROM actions
         JOIN customers
              ON customers.id = actions.customer_id
WHERE actions.action_type = 'CUSTOMER_TRAINING_BEGIN'
  AND actions.created IN (
    SELECT max(created)
    FROM actions
    WHERE action_type = 'CUSTOMER_TRAINING_BEGIN'
       OR action_type = 'CUSTOMER_TRAINING_END'
    GROUP BY customer_id
);

我尝试收集所有客户,其中最后一个状态(CUSTOMER_TRAINING_BEGIN 或 CUSTOMER_TRAINING_END)是 CUSTOMER_TRAINING_BEGIN。还有其他状态,但我只想要那些 2。

所以我有这些表:

                     Table "public.actions"  
   Column    |           Type           |       Modifiers           
-------------+--------------------------+------------------------   
 id          | bigint                   | not null   
 action_type | character varying(30)    | not null   
 user_name   | character varying(30)    | not null   
 customer_id | bigint                   |    
 created     | timestamp with time zone | not null default now()   
 updated     | timestamp with time zone | not null default now()   

                     Table "public.customers"
    Column    |           Type           |       Modifiers        
--------------+--------------------------+------------------------
 id           | integer                  | not null
 fore_name    | character varying(50)    | not null
 last_name    | character varying(50)    | not null
 matrikel     | integer                  | not null
 day_of_birth | timestamp with time zone | not null
 created      | timestamp with time zone | not null default now()
 updated      | timestamp with time zone | not null default now()

还有我的代码片段:

客户.java

@Data
@Entity
@NoArgsConstructor
@Table(name = "CUSTOMERS")
@EqualsAndHashCode(callSuper = false)
public class Customer extends AbstractTimestampEntity {

    @Id
    @SequenceGenerator(sequenceName = "CUSTOMERS_ID_SEQ", name = "CUSTOMERS_ID_GEN", allocationSize = 1)
    @GeneratedValue(generator = "CUSTOMERS_ID_GEN", strategy = GenerationType.SEQUENCE)
    private long id;

    @Column(name = "FORE_NAME")
    private String foreName;

    @Column(name = "LAST_NAME")
    private String lastName;

    @Column(name = "MATRIKEL")
    private int matrikelNumber;

    @Column(name = "DAY_OF_BIRTH")
    private Date dayOfBirth;

}

ActionType.java

@AllArgsConstructor
public enum ActionType {
    /**
     * Customer starts training.
     */
    CUSTOMER_TRAINING_BEGIN("ActionType.customerTrainingBegin.label"),
    /**
     * Customer stops training
     */
    CUSTOMER_TRAINING_END("ActionType.customerTrainingEnd.label");

    @Getter
    private String labelKey;
}

动作.java

@Data
@Entity
@Table(name = "ACTIONS")
@EqualsAndHashCode(callSuper = false)
public class Action extends AbstractTimestampEntity {
  
    @Id
    @SequenceGenerator(sequenceName = "ACTIONS_ID_SEQ", name = "actions_id_gen", allocationSize = 1)
    @GeneratedValue(generator = "actions_id_gen", strategy = GenerationType.SEQUENCE)
    private long id;
    
    @OneToOne
    @JoinColumn(name = "USER_NAME")
    private User user;
 
    @OneToOne
    @JoinColumn(name = "CUSTOMER_ID")
    private Customer customer;

    @Enumerated(EnumType.STRING)
    @Column(name = "ACTION_TYPE")
    private ActionType type;

}

我的问题是,我必须收集客户。我必须从行动加入到客户,因为我没有从客户到行动的参考。所以我不能做类似的事情:

CriteriaBuilder criteriaBuilder = this.em.getCriteriaBuilder();
CriteriaQuery<Customer> query = criteriaBuilder.createQuery(Customer.class);
Root<Customer> from = query.from(Customer.class);

query.select(from);

// Join here to action...

也许这有助于理解我的问题。非常感谢。

问候,切斯穆

4

1 回答 1

0

您还需要映射表的createdactions。然后您可以应用以下 JPQL 查询(请注意子选择中的更改;您设计 SQL 查询的方式,它不会带来您想要的结果):

SELECT a.customer
FROM Action a
WHERE a.type = 'CUSTOMER_TRAINING_BEGIN' 
AND a.created = 
(
SELECT max(created)
FROM Action
WHERE (type = 'CUSTOMER_TRAINING_BEGIN' 
OR type = 'CUSTOMER_TRAINING_END')
AND customer.id = a.customer.id
)
于 2013-11-20T20:01:48.507 回答