我正在使用Oracle数据库,并有学生表:
学生桌:
| COLUMN | TYPE |
| ----------- | ------------- |
| ID | VARCHAR2(200) |
| NAME | VARCHAR2(200) |
| AGE | NUMBER(5) |
| MAIN_CITY | VARCHAR2(200) |
| GENDER | VARCHAR2(50) |
| SCORE | FLOAT(5) |
'
我正在尝试将此SQL查询转换为query-dsl代码:
SELECT /*+ parallel(2)*/ *
FROM (WITH filtered_values(age, gender, main_city) AS
(
SELECT /*+ MATERIALIZE */ age, gender, main_city
FROM Students
-- GET CONDITIONS FROM USER AND FILTER THE QUERY USING WHERE
)
SELECT *
FROM (
SELECT age AS value, COUNT(*) AS row_count, 'age' AS column_name
FROM filtered_values
GROUP BY age
ORDER BY row_count)
WHERE rownum <= 5
UNION ALL (
SELECT *
FROM (
SELECT gender AS value, COUNT(*) AS row_count, 'gender' AS column_name
FROM filtered_values
GROUP BY gender
ORDER BY row_count)
WHERE rownum <= 5)
UNION ALL (
SELECT *
FROM (
SELECT main_city AS value, COUNT(*) AS row_count, 'main_city' AS column_name
FROM filtered_values
GROUP BY main_city
ORDER BY row_count)
WHERE rownum <= 5)
)
客户端提供的筛选器非常灵活,可以更改WITH查询,例如:
评分大于20时:
WITH filtered_values(年龄,性别,主要城市)AS(SELECT/*+ MATERIALIZE /年龄,性别,主要城市FROM分数〉20的学生)
其中城市为LA或NYC,评分在50 - 60之间:
WITH filtered_values(年龄,性别,主要城市)AS(SELECT/+ MATERIALIZE */年龄,性别,主要城市FROM学生WHERE主要城市IN('LA ',' NYC')AND分数〉= 50 AND分数〈= 60)
我使用的是QueryDsl版本5.0.0。
我创建了Java类:
学生:
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(schema = "PROD", name = "Students")
public class Student implements Serializable {
@Id
@Column(name = "ID")
private String id;
@Column(name = "NAME")
private String name;
@Column(name = "AGE")
private int age;
@Column(name = "MAIN_CITY")
private String mainCity;
@Column(name = "SCORE")
private float score;
}
聚合值:
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(schema = "PROD", name = "NOT_REAL_TABLE")
public class AggregationValues {
private int age;
private String gender;
private String mainCity;
}
聚合结果行:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AggregationResultRow {
private String value;
private long rowCount;
private String columnName;
}
我的代码是:
注意,this.getConditions(aggregationsRequest)
从客户端返回带有所有过滤器的BooleanBuilder。
private final QStudent table = QStudent.student;
private final QAggregationValues aggregationValues = QAggregationValues.aggregationValues;
public List<AggregationResultRow> getAggergations(AggregationRequest aggregationRequest) {
SubQueryExpression<AggregationValues> filteredValues = new BlazeJPAQuery<AggregationValues>(entityManager, criteriaBuilderFactory)
.select(Projections.constructor(AggregationValues.class,
this.table.age,
this.table.gender,
this.table.mainCity))
.from(this.table)
.where(this.getConditions(aggregationRequest));
BlazeJPAQuery<AggregationResultRow> ageSelect = new BlazeJPAQuery<AggregationResultRow>(entityManager, criteriaBuilderFactory)
.with(this.aggregationValues, filteredValues)
.select(Projections.constructor(AggregationResultRow.class, this.aggregationValues.age.as("value"),
this.aggregationValues.count().as("row_count"),
Expressions.asString("age").as("column_name")))
.from(this.aggregationValues)
.groupBy(this.aggregationValues.age);
BlazeJPAQuery<AggregationResultRow> genderSelect = new BlazeJPAQuery<AggregationResultRow>(entityManager, criteriaBuilderFactory)
.with(this.aggregationValues, filteredValues)
.select(Projections.constructor(AggregationResultRow.class, this.aggregationValues.gender.as("value"),
this.aggregationValues.count().as("row_count"),
Expressions.asString("gender").as("column_name")))
.from(this.aggregationValues)
.groupBy(this.aggregationValues.gender);
BlazeJPAQuery<AggregationResultRow> mainCitySelect = new BlazeJPAQuery<AggregationResultRow>(entityManager, criteriaBuilderFactory)
.with(this.aggregationValues, filteredValues)
.select(Projections.constructor(AggregationResultRow.class, this.aggregationValues.mainCity.as("value"),
this.aggregationValues.count().as("row_count"),
Expressions.asString("main_city").as("column_name")))
.from(this.aggregationValues)
.groupBy(this.aggregationValues.mainCity);
return ageSelect.unionAll(genderSelect, mainCitySelect).fetch();
}
但我得到了异常-java.lang.IllegalArgumentException: Don't mix union and from
我已经尝试了更多的代码想法,但没有工作,这一个看起来最接近我的查询。
有什么想法吗?
非常感谢,我会非常感激的!
1条答案
按热度按时间wvt8vs2t1#
所以我找到了一个折中的解决方案!我所做的是在类中添加autowired参数:
这个函数是:
现在我只需要在WITH子句中的select语句中添加物化,并与所有函数并行。有什么想法吗?