如何根据列值与没有关联的表进行 LEFT JOIN

Posted

技术标签:

【中文标题】如何根据列值与没有关联的表进行 LEFT JOIN【英文标题】:How to LEFT JOIN with tables without association depending on column value 【发布时间】:2021-01-22 18:49:48 【问题描述】:

目标是使用 JPA 实现下一个 SQL:

SELECT f.id as id, f.entity_name as entity_name, f.entity_id as entity_id,
   CASE f.entity_name
      WHEN 'active-substance' then a.name
      WHEN 'outcome' then o.name
      WHEN 'symptom' then s.name
      WHEN 'therapeutic-regime' then t.name
   END as entity_description
FROM feedback f
LEFT JOIN active_substance a ON f.entity_name = 'active-substance' AND f.entity_id = a.id
LEFT JOIN outcome o ON f.entity_name = 'outcome' AND f.entity_id = o.id
LEFT JOIN symptom s ON f.entity_name = 'symptom' AND f.entity_id = s.id
LEFT JOIN therapeutic_regime t ON f.entity_name = 'therapeutic-regime' AND f.entity_id = t.id

实体反馈

@Entity
@Table(name = "feedback")
public class Feedback 
    @Id
    private Long id;

    @NotNull
    @Column(name = "entity_name", nullable = false)
    private EntityFeedback entityName;

    @NotNull
    @Column(name = "entity_id", nullable = false)
    private Long entityId;

    @OneToOne(fetch = FetchType.LAZY)
    @LazyToOne(LazyToOneOption.NO_PROXY)
    @JoinColumn(name = "entity_id", referencedColumnName = "id", insertable = false, updatable = false)
    //@Where("entity_name = 'active-substance'")
    @NotFound(action = NotFoundAction.IGNORE)
    private ActiveSubstance activeSubstance;

    @OneToOne(fetch = FetchType.LAZY)
    @LazyToOne(LazyToOneOption.NO_PROXY)
    @JoinColumn(name = "entity_id", referencedColumnName = "id", insertable = false, updatable = false)
    //@Where(clause = "entity_name = 'outcome'")
    @NotFound(action = NotFoundAction.IGNORE)
    private Outcome outcome;

    @OneToOne(fetch = FetchType.LAZY)
    @LazyToOne(LazyToOneOption.NO_PROXY)
    @JoinColumn(name = "entity_id", referencedColumnName = "id", insertable = false, updatable = false)
    //@Where(clause = "entity_name = 'symptom'")
    @NotFound(action = NotFoundAction.IGNORE)
    @JsonIgnoreProperties(value =  "feedback" , allowSetters = true)
    private Symptom symptom;

    @OneToOne(fetch = FetchType.LAZY)
    @LazyToOne(LazyToOneOption.NO_PROXY)
    @JoinColumn(name = "entity_id", referencedColumnName = "id", insertable = false, updatable = false)
    //@Where(clause = "entity_name = 'therapeutic-regime'")
    @NotFound(action = NotFoundAction.IGNORE)
    @JsonIgnoreProperties(value =  "feedback" , allowSetters = true)
    private TherapeuticRegime therapeuticRegime;

...

查询中没有使用@Where

如何根据列 entity_name 值调整 LEFT JOIN?

查看了 Vlad Mihalcea 的博客,但没有发现任何类似的案例。

【问题讨论】:

@VladMihalcea 你有什么线索吗? 【参考方案1】:

您可以只使用与您提供的 SQL 示例非常相似的 HQL:

SELECT f.id as id, f.entityName, f.entityId,
   CASE f.entityName 
      WHEN 'active-substance' then a.name
      WHEN 'outcome' then o.name
      WHEN 'symptom' then s.name
      WHEN 'therapeutic-regime' then t.name
   END as entity_description
FROM Feedback f
LEFT JOIN ActiveSubstance a ON f.entityName = 'active-substance' AND f.entityId = a.id
LEFT JOIN Outcome o ON f.entityName = 'outcome' AND f.entityId = o.id
LEFT JOIN Symptom s ON f.entityName = 'symptom' AND f.entityId = s.id
LEFT JOIN TherapeuticRegime t ON f.entityName = 'therapeutic-regime' AND f.entityId = t.id

【讨论】:

以上是关于如何根据列值与没有关联的表进行 LEFT JOIN的主要内容,如果未能解决你的问题,请参考以下文章

MariaDB 根据列值连接来自不同数据库的表

浅谈!SQL语句中LEFT JOIN ON WHERE和LEFT JOIN ON AND的区别

left join on和where

left join 右边没有值如何设置默认值

HIVE JOIN 两个具有不同行数的表给出错误的列值

两个表进行左连接(LEFT JOIN ) 如何只显示右表中为空值的记录行,左表与右表存在关联的记录不显示。