我尝试将此查询映射到JPA,加入,子查询和其他对我来说非常重要。也许你可以帮助我。这是我的疑问:
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()
我的代码片段:
Customer.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;
}
Action.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...
也许这有助于理解我的问题。非常感谢。
问候,Chesmuh
答案 0 :(得分:0)
您还需要映射created
表的actions
列。然后,您可以应用以下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
)