当前位置: 首页 > 知识库问答 >
问题:

SQL查询太复杂,无法在JPA标准API中表达?

罗昕
2023-03-14

SQL:

SELECT w.NAME   AS 'wave_name', 
   Count(*) AS 'num_lines', 
   Sum(qty_ordered) AS 'num_units', 
   Count(DISTINCT unit_of_work_id) AS 'num_units_of_work', 
   Sum(completed_units) AS 'completed_units', 
   ( Sum(completed_units) + Sum(qty_scratched) ) / Sum(qty_ordered) AS 'perc_completed_units' 
FROM   (SELECT t.id, 
           t.wave_id, 
           t.quantity_requested  AS 'qty_ordered', 
           t.quantity_scratched    AS 'qty_scratched', 
           t.unit_of_work_id     AS 'unit_of_work_id', 
           Ifnull(m.quantity, 0) AS 'qty_picked', 
           CASE 
             WHEN Ifnull(m.quantity, 0) > quantity_requested THEN 
             quantity_requested 
             ELSE Ifnull(m.quantity, 0) 
           END                   AS 'completed_units' 
    FROM   task t 
           LEFT OUTER JOIN (SELECT move.task_id, 
                                   Sum(quantity) AS 'quantity' 
                            FROM   move
                            GROUP  BY task_id) m 
                        ON m.task_id = t.id) s 
   JOIN wave w 
     ON w.id = s.wave_id 
GROUP  BY w.name;

各实体:

@Entity
@Table(name = "task")
public class Task {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private Long id;

    @ManyToOne (cascade = CascadeType.ALL)
    @JoinColumn (name = "wave_id", nullable = false)
    private Wave wave;

    @ManyToOne (cascade = CascadeType.ALL)
    @JoinColumn (name = "unit_of_work_id", nullable = false)
    private UnitOfWork unitOfWork;

    @OneToMany (cascade = CascadeType.ALL, mappedBy = "task")
    private Set<Move> moves = new HashSet<Move>();

    @Column (name = "quantity_requested")
    private Long quantityRequested;

    @Column (name = "quantity_scratched")
    private Long quantityScratched;
}

@Entity
@Table(name = "wave")
public class Wave {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

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

    @OneToMany(mappedBy = "wave", cascade = CascadeType.ALL)
    private Set<Task> tasks = new HashSet<Task>();
}

@Entity
@Table(name = "unit_of_work")
public class UnitOfWork {

    @Id
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    @Column (name = "id")
    private Long id;

    @OneToMany(mappedBy = "unitOfWork", cascade = CascadeType.ALL)
    private Set<Task> tasks = new HashSet<Task>();
}

@Entity
@Table(name = "move")
public class Move {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private Long id;

    @ManyToOne (cascade = CascadeType.ALL)
    @JoinColumn (name = "task_id", nullable = false)
    private Task task;

    @Column (name = "quantity")
    private Long quantity;
}

共有1个答案

夏侯兴学
2023-03-14

我建议使用命名参数或本机查询方法。

例如:

命名参数:

 public interface Repo extends JpaRepository<AEntity, String> { 
    @Query("select a from AEntity a where a.BEntity.name = :name")

    public aMethod( @Param("name") String name)
    }
public interface Repo extends JpaRepository<AEntity, String> {    
    @Query(value = "select * from Tablename t where t.name = :name", nativeQuery=true)

    public aMethod(@Param("name") String name)
    }
 类似资料:
  • 我有2个班: 我试图创建一个带有动态order by和参数的查询,例如:我想在DrcommentsPK时选择所有Drcomments记录。commentPrimaryCode等于1,其顺序为DrcommentsPK。注释第二代码。这就是我尝试的: 问题是我得到的结果列表没有按commentSecondaryCode desc顺序排序。。 我做错什么了吗?如何做到这一点?如何创建按eMedTable

  • 问题内容: 我有以下ManyToMany映射。 我想检索与Classe2实体有关系的所有Class1实体,其中class2Id = 1和class2Id = 2和class2Id = 3。{1,2,3} 或者,要过滤在其class2列表上具有的Classe1实体,请使用具有以下值的Class2实体:class2Id = 1和class2Id = 2和class2Id = 3 例如: 如果在联接表上

  • 我的问题是空值必须是最后一个order by语句。下面是我的代码截图。我使用javax持久性标准生成器。我的问题很复杂。 如何通过criteria builder以零价格完成订单?

  • 如何将这个复杂的sql语句更改为JPQL? 这是否可以在JPQL表单中显示?

  • 我有一张这样的桌子: 现在我想创建一个返回经过过滤的数据集的REST APIendpoint: 它应正确筛选API参数的任何组合。 所有参数都是可选的 看看这个示例: 我想要能够过滤基于每个参数或组合的2或参数。 我应该如何编写@RequestParam?这是一个复杂的查询。对此有何策略?

  • 我得到了以下许多映射。 我想检索所有与Classe2实体有关系的Class1实体,它们的类2Id=1和类2Id=2和类2Id=3。{1,2,3} 或者,要筛选在其class2列表上具有值的Class1实体,请使用值class2Id=1、class2Id=2和class2Id=3的class2实体 例如: 如果在联接表上,我得到了以下值。 对于这个例子,结果将是类1Id为1和6的类1。因为类1实体,