京东实习过程中用到了UNION查询,遇到不少问题,记录一下
这条sql语句的大体逻辑是这样的:需要从多张表中查询两种不同类型的数据,用UNION合并后,用动态sql语句来筛选,最后将所有数据排序
UNION查询中的字段顺序
首先,两条select语句合并后再用where来筛选数据的方式有两种,为了方便已经将字段简化,下面为一种,也可以在两条select语句中先where筛选,之后使用UNION合并
<select id="queryList" resultType="**VO" parameterType="**VO">
SELECT * FROM (
SELECT
t.tenant_code,o.object_subject,t.kr_code,t.object_code,
IF(date_format(NOW(),'%Y-%m-%d') <![CDATA[>]]> t.end_date, TRUE, FALSE) AS overdue
FROM
task t,
objective o
WHERE
t.yn=1
AND t.object_code = o.object_code
UNION ALL
SELECT
t.tenant_code,o.object_subject,null,null,
IF(date_format(NOW(),'%Y-%m-%d') <![CDATA[>]]> t.end_date, TRUE, FALSE) AS overdue
FROM
task t
WHERE
t.type='normal'
) AS A
WHERE
A.overdue = 0
<if test="taskType != null">
AND A.task_type = #{taskType}
</if>
ORDER BY sort ASC,id ASC
</select>
上面的sql语句中有几点需要注意的:
- 被<![CDATA[]]>这个标记所包含的内容将表示为纯文本,比如<![CDATA[>]]>表示文本内容“>”,因为sql语句是在xml文件中写的,在xml中,”<”、”>”、”&”等字符是不能直接存入的
- 第二条select语句中查询字段有两个null,因为union要求两个select语句的结果中的列必须是完全同名且同顺序的,但是如果列数量不同怎么办,可以用null来替代,不然sql会报错
The used SELECT statements have a different number of columns
- 在使用union查询后排序,需要指定临时表名,即上面代码中的
SELECT * FROM (***) AS A
,不然报错Every derived table must have its own alias
UNION和UNION ALL的区别
UNION 操作会对结果去重且排序,而UNION ALL会直接返回合并结果,不做处理,所以UNION ALL的速度会更快,根据需求进行选择
P.S. 实体类entity要根据使用场景不同来命名,Bo(business object)代表业务对象,Vo(value object)为值对象,通常同于和视图层进行交互,即后台和前端之间的传递对象,Po(persistant object)代表持久层对象的意思,对应数据库中表的字段