求一条SQL,问题详情在文章里

Raven丶 2019-05-10 04:26:47
老大加了一个新需求,通过前端传两个参数过来,一个开始时间(startTime)和结束时间(endTime),在Mybatis.xml里我是这么写的,
<select id="getMerchantByPos" resultMap="PosMap">
select
T.MERCHANT_ID
from T_POS T
<where>
1=1
<if test="startTime != null and endTime != null ">
AND ( TO_CHAR(T.CREATETIME,'yyyy-mm-dd' ) BETWEEN TO_CHAR(sysdate'yyyy-mm-dd' ) AND TO_CHAR(sysdate'yyyy-mm-dd' ))
AND SELECT c.* FROM T_MERCHANT C WHERE C.MERCHANT_ID not IN ( select distinct T.MERCHANT_ID AS ID2 from t_pos T where
(TO_CHAR(T.CREATETIME, 'yyyy-mm-dd') BETWEEN TO_CHAR(sysdate 'yyyy-mm-dd') AND TO_CHAR(sysdate 'yyyy-mm-dd')))
</if>
</where>
</select>
仅此而已,但是没用,
bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00936: 缺失表达式
郁闷一天了,还是不知道哪里错了
...全文
280 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Raven丶 2019-05-20
  • 打赏
  • 举报
回复
<select id="getMerchantByPos" resultMap="MerchantMap" parameterType="map">
SELECT
M.*
FROM
T_MERCHANT M
<where>
1=1
<if test="startTime != null and endTime != null ">
AND M.MERCHANT_ID IN (
select tPos.MERCHANT_ID from T_POS tPos where tPos.TRADE_MONEY IS NULL AND(TO_CHAR(tPos.TRADE_DATE, 'yyyy-mm-dd') BETWEEN #{startTime}
AND #{endTime}))
</if>
</where>
</select>
谢谢各位大佬的指点,已经完成了!
林会 2019-05-13
  • 打赏
  • 举报
回复
引用 10 楼 Raven丶 的回复:
[quote=引用 6 楼 林会 的回复:] <if test="begintTime!=null and begintTime!=''"> <![CDATA[ and DATE_FORMAT(CREATE_DATE, '%Y-%m-%d') >= DATE_FORMAT(#{begintTime}, '%Y-%m-%d') ]]> </if> <if test="endTime!=null and endTime!=''"> <![CDATA[ and DATE_FORMAT(CREATE_DATE, '%Y-%m-%d') <= DATE_FORMAT(#{endTime}, '%Y-%m-%d') ]]> </if> 在mybatis中直接这样写就可以,传入的参数直接就是java的Date类型
大佬,你这个是对的,单纯的取时间段没问题,我上面忘记描述我的功能了,功能是在前台传入一个开始时间和结束时间,然后查出这个时间段内数据为空的商户ID,我比较依赖SQL,能不能麻烦你解答一下,[/quote] select id from table_name where 你说的数据 is null and 上面写的时间查询
nayi_224 2019-05-13
  • 打赏
  • 举报
回复
引用 13 楼 nayi_224 的回复:
and ( to_char(t.createtime,'yyyy-mm-dd' )  between  to_char(sysdate'yyyy-mm-dd' ) and to_char(sysdate'yyyy-mm-dd' ))
and not exists(
select 1 from t_merchant c where c.merchant_id = t.merchant_id
)
中间楼层没看,就是把语法错误的sql重写了一遍。
nayi_224 2019-05-13
  • 打赏
  • 举报
回复
and ( to_char(t.createtime,'yyyy-mm-dd' )  between  to_char(sysdate'yyyy-mm-dd' ) and to_char(sysdate'yyyy-mm-dd' ))
and not exists(
select 1 from t_merchant c where c.merchant_id = t.merchant_id
)
Raven丶 2019-05-13
  • 打赏
  • 举报
回复
引用 8 楼 代码间的舞者 的回复:

<select id="getMerchantByPos" resultMap="PosMap">
select
T.MERCHANT_ID
from T_POS T
<where>
1=1
<if test="startTime != null and endTime != null ">
AND ( TO_CHAR(T.CREATETIME,'yyyy-mm-dd' ) BETWEEN TO_CHAR(sysdate'yyyy-mm-dd' ) AND TO_CHAR(sysdate'yyyy-mm-dd' ))
AND SELECT c.* FROM T_MERCHANT C WHERE C.MERCHANT_ID not IN ( select distinct T.MERCHANT_ID AS ID2 from t_pos T where
(TO_CHAR(T.CREATETIME, 'yyyy-mm-dd') BETWEEN TO_CHAR(sysdate 'yyyy-mm-dd') AND TO_CHAR(sysdate 'yyyy-mm-dd')))
</if>
</where>
</select>


红色部分,少了逗号
没有呢! 格式在plsql里面都能运行了,就是不清楚这个查询时间段内数据为空的业务该怎么写
Raven丶 2019-05-13
  • 打赏
  • 举报
回复
引用 7 楼 对梦想的牵挂 的回复:
[quote=引用 3 楼 Raven丶 的回复:]
[quote=引用 1 楼 对梦想的牵挂 的回复:]
是要拿开始时间(startTime)和结束时间(endTime)之间的数据吗?拼SQL的时候不应该这么写吧:“AND SELECT c.* FROM T_MERCHANT C ”。select查出来的结果集应该在where子句外面。select a.*,b.* from a,b 这种的。
建议把执行SQL打印出来,放到客户端执行,这样一看便知错误在哪里了。
Oracle客户端没问题,改了之后:

<select id="getMerchantByPos" resultMap="PosMap">
SELECT
c.*
FROM T_MERCHANT C
<where>
1=1
<if test="startTime != null and endTime != null ">
AND C.MERCHANT_ID not IN ( select distinct T.MERCHANT_ID AS ID2 from t_pos T where
(TO_CHAR(T.CREATETIME, 'yyyy-mm-dd') BETWEEN TO_CHAR(#{startTime}, 'yyyy-mm-dd') AND TO_CHAR(#{endTime}, 'yyyy-mm-dd')))
</if>
</where>
</select>
又出现无效数字,是startTime和endTime的格式问题,[/quote]
先确认一下startTime是什么数据类型,如果是时间类型试试改成下面这种接收方式
#{startTime,jdbcType=TIMESTAMP}[/quote]好像没什么用,谢谢了好
Raven丶 2019-05-13
  • 打赏
  • 举报
回复
引用 6 楼 林会 的回复:
<if test="begintTime!=null and begintTime!=''">
<![CDATA[ and DATE_FORMAT(CREATE_DATE, '%Y-%m-%d') >= DATE_FORMAT(#{begintTime}, '%Y-%m-%d') ]]>
</if>
<if test="endTime!=null and endTime!=''">
<![CDATA[ and DATE_FORMAT(CREATE_DATE, '%Y-%m-%d') <= DATE_FORMAT(#{endTime}, '%Y-%m-%d') ]]>
</if>
在mybatis中直接这样写就可以,传入的参数直接就是java的Date类型
大佬,你这个是对的,单纯的取时间段没问题,我上面忘记描述我的功能了,功能是在前台传入一个开始时间和结束时间,然后查出这个时间段内数据为空的商户ID,我比较依赖SQL,能不能麻烦你解答一下,
代码间的舞者 2019-05-11
  • 打赏
  • 举报
回复
引用 8 楼 代码间的舞者 的回复:

<select id="getMerchantByPos" resultMap="PosMap">
select
T.MERCHANT_ID
from T_POS T
<where>
1=1
<if test="startTime != null and endTime != null ">
AND ( TO_CHAR(T.CREATETIME,'yyyy-mm-dd' ) BETWEEN TO_CHAR(sysdate'yyyy-mm-dd' ) AND TO_CHAR(sysdate'yyyy-mm-dd' ))
AND SELECT c.* FROM T_MERCHANT C WHERE C.MERCHANT_ID not IN ( select distinct T.MERCHANT_ID AS ID2 from t_pos T where
(TO_CHAR(T.CREATETIME, 'yyyy-mm-dd') BETWEEN TO_CHAR(sysdate 'yyyy-mm-dd') AND TO_CHAR(sysdate 'yyyy-mm-dd')))
</if>
</where>
</select>


红色部分,少了逗号


TO_CHAR(sysdate'yyyy-mm-dd' ) 改成 TO_CHAR(sysdate,'yyyy-mm-dd' )
代码间的舞者 2019-05-11
  • 打赏
  • 举报
回复

<select id="getMerchantByPos" resultMap="PosMap">
select
T.MERCHANT_ID
from T_POS T
<where>
1=1
<if test="startTime != null and endTime != null ">
AND ( TO_CHAR(T.CREATETIME,'yyyy-mm-dd' ) BETWEEN TO_CHAR(sysdate'yyyy-mm-dd' ) AND TO_CHAR(sysdate'yyyy-mm-dd' ))
AND SELECT c.* FROM T_MERCHANT C WHERE C.MERCHANT_ID not IN ( select distinct T.MERCHANT_ID AS ID2 from t_pos T where
(TO_CHAR(T.CREATETIME, 'yyyy-mm-dd') BETWEEN TO_CHAR(sysdate 'yyyy-mm-dd') AND TO_CHAR(sysdate 'yyyy-mm-dd')))
</if>
</where>
</select>


红色部分,少了逗号
对梦想的牵挂 2019-05-10
  • 打赏
  • 举报
回复
引用 3 楼 Raven丶 的回复:
[quote=引用 1 楼 对梦想的牵挂 的回复:] 是要拿开始时间(startTime)和结束时间(endTime)之间的数据吗?拼SQL的时候不应该这么写吧:“AND SELECT c.* FROM T_MERCHANT C ”。select查出来的结果集应该在where子句外面。select a.*,b.* from a,b 这种的。 建议把执行SQL打印出来,放到客户端执行,这样一看便知错误在哪里了。
Oracle客户端没问题,改了之后: <select id="getMerchantByPos" resultMap="PosMap"> SELECT c.* FROM T_MERCHANT C <where> 1=1 <if test="startTime != null and endTime != null "> AND C.MERCHANT_ID not IN ( select distinct T.MERCHANT_ID AS ID2 from t_pos T where (TO_CHAR(T.CREATETIME, 'yyyy-mm-dd') BETWEEN TO_CHAR(#{startTime}, 'yyyy-mm-dd') AND TO_CHAR(#{endTime}, 'yyyy-mm-dd'))) </if> </where> </select> 又出现无效数字,是startTime和endTime的格式问题,[/quote] 先确认一下startTime是什么数据类型,如果是时间类型试试改成下面这种接收方式 #{startTime,jdbcType=TIMESTAMP}
林会 2019-05-10
  • 打赏
  • 举报
回复
<if test="begintTime!=null and begintTime!=''"> <![CDATA[ and DATE_FORMAT(CREATE_DATE, '%Y-%m-%d') >= DATE_FORMAT(#{begintTime}, '%Y-%m-%d') ]]> </if> <if test="endTime!=null and endTime!=''"> <![CDATA[ and DATE_FORMAT(CREATE_DATE, '%Y-%m-%d') <= DATE_FORMAT(#{endTime}, '%Y-%m-%d') ]]> </if> 在mybatis中直接这样写就可以,传入的参数直接就是java的Date类型
帝大人狠 2019-05-10
  • 打赏
  • 举报
回复
引用 4 楼 Raven丶 的回复:
引用 2 楼 qq_40865925 的回复:
是mysql么?
是Oracle的,烦躁不是一般的
首先确定sql本身没有问题哦,比如你的select语句放在where里面就要注意一下,然后确认你的版本是否支持 TO_CHAR 以及 BETWEEN函数,先简化一些条件一个一个问题查找就好,我这边是mysql,没法使用oracle
Raven丶 2019-05-10
  • 打赏
  • 举报
回复
引用 2 楼 qq_40865925 的回复:
是mysql么?
是Oracle的,烦躁不是一般的
Raven丶 2019-05-10
  • 打赏
  • 举报
回复
引用 1 楼 对梦想的牵挂 的回复:
是要拿开始时间(startTime)和结束时间(endTime)之间的数据吗?拼SQL的时候不应该这么写吧:“AND SELECT c.* FROM T_MERCHANT C ”。select查出来的结果集应该在where子句外面。select a.*,b.* from a,b 这种的。
建议把执行SQL打印出来,放到客户端执行,这样一看便知错误在哪里了。
Oracle客户端没问题,改了之后:

<select id="getMerchantByPos" resultMap="PosMap">
SELECT
c.*
FROM T_MERCHANT C
<where>
1=1
<if test="startTime != null and endTime != null ">
AND C.MERCHANT_ID not IN ( select distinct T.MERCHANT_ID AS ID2 from t_pos T where
(TO_CHAR(T.CREATETIME, 'yyyy-mm-dd') BETWEEN TO_CHAR(#{startTime}, 'yyyy-mm-dd') AND TO_CHAR(#{endTime}, 'yyyy-mm-dd')))
</if>
</where>
</select>
又出现无效数字,是startTime和endTime的格式问题,
帝大人狠 2019-05-10
  • 打赏
  • 举报
回复
是mysql么?
对梦想的牵挂 2019-05-10
  • 打赏
  • 举报
回复
是要拿开始时间(startTime)和结束时间(endTime)之间的数据吗?拼SQL的时候不应该这么写吧:“AND SELECT c.* FROM T_MERCHANT C ”。select查出来的结果集应该在where子句外面。select a.*,b.* from a,b 这种的。 建议把执行SQL打印出来,放到客户端执行,这样一看便知错误在哪里了。

67,538

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧