尝试解决SQL查询问题

时间:2016-07-09 05:51:07

标签: sql oracle

我在SQL查询下面有两个这样的日期时间标准不同,一个会返回数据而另一个则不会......有人可以帮忙......?

返回数据的查询 -

SELECT *
FROM CA_CLN_CAPM_TRANSPORT,
  CA_ENCOUNTER_REF TRANSPORT_PATIENT_ENCOUNTER,
  (SELECT DISTINCT TRANSPORT_PATIENT_ATTRIBUTES.ENCOUNTER_ID,
    TRANSPORT_PATIENT_ATTRIBUTES.ATTRIBUTE_NAME
  FROM CA_CAPM_ENCOUNTER_ATTR TRANSPORT_PATIENT_ATTRIBUTES,
    CA_CLN_CAPM_TRANSPORT
  WHERE (CA_CLN_CAPM_TRANSPORT.SCHEDULED_DTTM BETWEEN TRANSPORT_PATIENT_ATTRIBUTES.EFF_BEGIN_DTTM AND NVL(TRANSPORT_PATIENT_ATTRIBUTES.EFF_END_DTTM,SYSDATE)
  OR NVL(CA_CLN_CAPM_TRANSPORT.COMPLETE_DTTM,SYSDATE) BETWEEN TRANSPORT_PATIENT_ATTRIBUTES.EFF_BEGIN_DTTM AND NVL(TRANSPORT_PATIENT_ATTRIBUTES.EFF_END_DTTM,SYSDATE)
  OR TRANSPORT_PATIENT_ATTRIBUTES.EFF_BEGIN_DTTM BETWEEN CA_CLN_CAPM_TRANSPORT.SCHEDULED_DTTM AND NVL(CA_CLN_CAPM_TRANSPORT.COMPLETE_DTTM,SYSDATE))
  AND CAST(CA_CLN_CAPM_TRANSPORT.SCHEDULED_DTTM AS DATE) BETWEEN '30-06-2016 12:00:00' AND **'30-06-2016 23:59:00'**
  ) PATIENT_ATTRIBUTES
WHERE CA_CLN_CAPM_TRANSPORT.ENCOUNTER_ID      = TRANSPORT_PATIENT_ENCOUNTER.ENCOUNTER_ID
AND TRANSPORT_PATIENT_ENCOUNTER.ENCOUNTER_ID  = PATIENT_ATTRIBUTES.ENCOUNTER_ID(+)
AND TRANSPORT_PATIENT_ENCOUNTER.PATIENT_ID <> '0'
AND CAST(CA_CLN_CAPM_TRANSPORT.SCHEDULED_DTTM AS DATE) BETWEEN '30-06-2016 12:00:00' AND **'30-06-2016 23:59:00'**;

不返回数据的查询 -

SELECT *
FROM CA_CLN_CAPM_TRANSPORT,
  CA_ENCOUNTER_REF TRANSPORT_PATIENT_ENCOUNTER,
  (SELECT DISTINCT TRANSPORT_PATIENT_ATTRIBUTES.ENCOUNTER_ID,
    TRANSPORT_PATIENT_ATTRIBUTES.ATTRIBUTE_NAME
  FROM CA_CAPM_ENCOUNTER_ATTR TRANSPORT_PATIENT_ATTRIBUTES,
    CA_CLN_CAPM_TRANSPORT
  WHERE (CA_CLN_CAPM_TRANSPORT.SCHEDULED_DTTM BETWEEN TRANSPORT_PATIENT_ATTRIBUTES.EFF_BEGIN_DTTM AND NVL(TRANSPORT_PATIENT_ATTRIBUTES.EFF_END_DTTM,SYSDATE)
  OR NVL(CA_CLN_CAPM_TRANSPORT.COMPLETE_DTTM,SYSDATE) BETWEEN TRANSPORT_PATIENT_ATTRIBUTES.EFF_BEGIN_DTTM AND NVL(TRANSPORT_PATIENT_ATTRIBUTES.EFF_END_DTTM,SYSDATE)
  OR TRANSPORT_PATIENT_ATTRIBUTES.EFF_BEGIN_DTTM BETWEEN CA_CLN_CAPM_TRANSPORT.SCHEDULED_DTTM AND NVL(CA_CLN_CAPM_TRANSPORT.COMPLETE_DTTM,SYSDATE))
  AND CAST(CA_CLN_CAPM_TRANSPORT.SCHEDULED_DTTM AS DATE) BETWEEN '30-06-2016 12:00:00' AND **'01-07-2016 23:59:00'** –Running for longer time frame
  ) PATIENT_ATTRIBUTES
WHERE CA_CLN_CAPM_TRANSPORT.ENCOUNTER_ID      = TRANSPORT_PATIENT_ENCOUNTER.ENCOUNTER_ID
AND TRANSPORT_PATIENT_ENCOUNTER.ENCOUNTER_ID  = PATIENT_ATTRIBUTES.ENCOUNTER_ID(+)
AND TRANSPORT_PATIENT_ENCOUNTER.PATIENT_ID <> '0'
AND CAST(CA_CLN_CAPM_TRANSPORT.SCHEDULED_DTTM AS DATE) BETWEEN '30-06-2016 12:00:00' AND **'01-07-2016 23:59:00'**; 

1 个答案:

答案 0 :(得分:0)

问题是您使用字符串来表示日期时间值。如果我们在您的字符串上运行DUMP(),我们就会得到:

SQL> select dump('30-06-2016 12:00:00') as dt 
  2  from dual
  3  /

DT
-----------------------------------------------------------------------
Typ=96 Len=19: 51,48,45,48,54,45,50,48,49,54,32,49,50,58,48,48,58,48,48

SQL> 

Typ=96表示它a CHAR value(日期为Typ=12)。因此Oracle将对操作应用字符语义。实际上这......

x BETWEEN '30-06-2016 12:00:00' AND '01-07-2016 23:59:00'

...评估为......

'30' >= '30' AND '30' <= '01' 

......这显然是胡说八道。

您需要做的是使用带格式掩码的显式强制转换:

BETWEEN to_date('30-06-2016 12:00:00', 'DD-MM-YYYY HH24:MI:SS') 
    AND to_date('01-07-2016 23:59:00', 'DD-MM-YYYY HH24:MI:SS')