我在Oracle SQL Query下面一直给我一个错误。我错过了右括号错误。我试着寻找缺失的括号,但它们似乎都在记事本编辑器中正确关闭。
SELECT EMPLOYEES.EMPLOYEEID, EMPLOYEES.NAME FROM EMPLOYEES WHERE Employees.EmployeeID NOT IN
(
SELECT Services.EmployeeID FROM Services where
SERVICES.CHECKOUT <>3 AND SERVICES.CHECKOUT <> 5 AND SERVICES.CHECKOUT <>6
AND
(
TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS' BETWEEN SERVICES.STARTDATE AND SERVICES.ENDDATE) or
TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS' BETWEEN SERVICES.STARTDATE AND SERVICES.ENDDATE) or
SERVICES.STARTDATE BETWEEN TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS') AND TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS') or
SERVICES.ENDDATE BETWEEN TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS') AND TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS')
)
union
SELECT EMPBREAKS.EMPID FROM EMPBREAKS WHERE
TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS') BETWEEN EMPBREAKS.STARTB AND EMPBREAKS.ENDB or
TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS') BETWEEN EMPBREAKS.STARTB AND EMPBREAKS.ENDB or
EMPBREAKS.STARTB BETWEEN TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS') AND TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS') or
EMPBREAKS.ENDB BETWEEN TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS') AND TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS') or
(EMPBREAKS.FLAGCYCLIC =1 AND EMPBREAKS.DAYWEEKINDEX = 4 AND TO_DATE(TO_CHAR(EMPBREAKS.STARTB,'HH24:MI:SS'),'HH24:MI:SS') BETWEEN TO_DATE('11:00:00', 'HH24:MI:SS') AND TO_DATE('12:00:00', 'HH24:MI:SS')) or
(EMPBREAKS.FLAGCYCLIC =1 AND EMPBREAKS.DAYWEEKINDEX = 4 AND TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'),'HH24:MI:SS') BETWEEN TO_DATE('11:00:00', 'HH24:MI:SS') AND TO_DATE('12:00:00', 'HH24:MI:SS')) or
(EMPBREAKS.FLAGCYCLIC =1 AND EMPBREAKS.DAYWEEKINDEX = 4 AND TO_DATE('11:00:00', 'HH24:MI:SS') BETWEEN TO_DATE(TO_CHAR(EMPBREAKS.STARTB, 'HH24:MI:SS'),'HH24:MI:SS') AND TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'),'HH24:MI:SS')) or
(EMPBREAKS.FLAGCYCLIC =1 AND EMPBREAKS.DAYWEEKINDEX = 4 AND TO_DATE('12:00:00', 'HH24:MI:SS') BETWEEN TO_DATE(TO_CHAR(EMPBREAKS.STARTB, 'HH24:MI:SS', 'HH24:MI:SS') AND TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'),'HH24:MI:SS')))
union
SELECT EMPSICKVACATIONS.EMP_NO FROM EMPSICKVACATIONS Where EMPSICKVACATIONS.VDATE = TO_DATE('19/06/2017 00:00:00', 'DD/MM/YYYY HH24:MI:SS') or (EMPSICKVACATIONS.CYCLICFLAG = 1 AND EMPSICKVACATIONS.WEEKDAYINDEX = 4))
答案 0 :(得分:2)
虽然您还没有让我们知道此查询产生了什么样的错误,但Oracle通常不会将多个左括号放在一起,尤其是在不需要它们的情况下。此外,您反复使用相同的常量 - 最好将它们放在表表达式中,然后将其交叉连接到子查询,以避免多次重新键入它们。重新格式化查询以消除不必要的括号,使其更具可读性,并使用表表达式来消除我们得到的常量:
WITH QUERY_DATA AS (SELECT TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS') AS DT11,
TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS') AS DT12,
TO_DATE('11:00:00', 'HH24:MI:SS') AS HH11,
TO_DATE('12:00:00', 'HH24:MI:SS') AS HH12)
SELECT EMPLOYEES.EMPLOYEEID, EMPLOYEES.NAME
FROM EMPLOYEES
WHERE EMPLOYEES.EMPLOYEEID NOT IN
(SELECT SERVICES.EMPLOYEEID
FROM SERVICES
CROSS JOIN QUERY_DATA q
WHERE SERVICES.CHECKOUT <> 3 AND
SERVICES.CHECKOUT <> 5 AND
SERVICES.CHECKOUT <> 6 AND
(q.DT11 BETWEEN SERVICES.STARTDATE
AND SERVICES.ENDDATE OR
q.DT12 BETWEEN SERVICES.STARTDATE
AND SERVICES.ENDDATE OR
SERVICES.STARTDATE BETWEEN q.DT11
AND q.DT12 OR
SERVICES.ENDDATE BETWEEN q.DT11
AND q.DT12)
UNION
SELECT EMPBREAKS.EMPID
FROM EMPBREAKS
CROSS JOIN QUERY_DATA
WHERE q.DT11 BETWEEN EMPBREAKS.STARTB
AND EMPBREAKS.ENDB OR
q.DT12 BETWEEN EMPBREAKS.STARTB
AND EMPBREAKS.ENDB OR
EMPBREAKS.STARTB BETWEEN q.DT12
AND q.DT11 OR
EMPBREAKS.ENDB BETWEEN q.DT12
AND q.DT11 OR
(EMPBREAKS.FLAGCYCLIC = 1 AND
EMPBREAKS.DAYWEEKINDEX = 4 AND
TO_DATE(TO_CHAR(EMPBREAKS.STARTB,'HH24:MI:SS'),'HH24:MI:SS') BETWEEN q.HH11
AND q.HH12) OR
(EMPBREAKS.FLAGCYCLIC = 1 AND
EMPBREAKS.DAYWEEKINDEX = 4 AND
TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'),'HH24:MI:SS') BETWEEN q.HH11
AND q.HH12) OR
(EMPBREAKS.FLAGCYCLIC = 1 AND
EMPBREAKS.DAYWEEKINDEX = 4 AND
q.HH11 BETWEEN TO_DATE(TO_CHAR(EMPBREAKS.STARTB, 'HH24:MI:SS'),'HH24:MI:SS')
AND TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'),'HH24:MI:SS')) OR
(EMPBREAKS.FLAGCYCLIC = 1 AND
EMPBREAKS.DAYWEEKINDEX = 4 AND
q.HH12 BETWEEN TO_DATE(TO_CHAR(EMPBREAKS.STARTB, 'HH24:MI:SS', 'HH24:MI:SS')
AND TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'),'HH24:MI:SS')))
UNION
SELECT EMPSICKVACATIONS.EMP_NO
FROM EMPSICKVACATIONS
Where EMPSICKVACATIONS.VDATE = TO_DATE('19/06/2017 00:00:00', 'DD/MM/YYYY HH24:MI:SS') OR
(EMPSICKVACATIONS.CYCLICFLAG = 1 AND
EMPSICKVACATIONS.WEEKDAYINDEX = 4))
稍微观察一下,您会注意到在UNION
的第二个查询中,有几个表达式看起来像
EMPBREAKS.STARTB BETWEEN q.DT12
AND q.DT11 OR
EMPBREAKS.ENDB BETWEEN q.DT12
AND q.DT11 OR
这将是一个问题,因为第一个日期(QUERY_DATA.DT12)大于第二个日期(QUERY_DATA.DT11)。在BETWEEN
表达式中,第一个值必须小于或等于第二个值,否则永远不会满足表达式。这些应该改写为
EMPBREAKS.STARTB BETWEEN q.DT11
AND q.DT12 OR
EMPBREAKS.ENDB BETWEEN q.DT11
AND q.DT12 OR
祝你好运。
答案 1 :(得分:1)
解决这些问题
SELECT EMPLOYEES.EMPLOYEEID,
EMPLOYEES.NAME
FROM EMPLOYEES
WHERE Employees.EmployeeID NOT IN (
(
SELECT Services.EmployeeID
FROM Services
WHERE
(
(
SERVICES.CHECKOUT <>3
AND SERVICES.CHECKOUT <> 5
AND SERVICES.CHECKOUT <>6
)
AND
(
(
TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS') BETWEEN
SERVICES.STARTDATE AND SERVICES.ENDDATE
)
OR
(
TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS') BETWEEN
SERVICES.STARTDATE AND SERVICES.ENDDATE
)
OR
(
SERVICES.STARTDATE BETWEEN TO_DATE('29/06/2017 11:00:00',
'DD/MM/YYYY HH24:MI:SS') AND TO_DATE('29/06/2017 12:00:00',
'DD/MM/YYYY HH24:MI:SS')
)
OR
(
SERVICES.ENDDATE BETWEEN TO_DATE('29/06/2017 11:00:00',
'DD/MM/YYYY HH24:MI:SS') AND TO_DATE('29/06/2017 12:00:00',
'DD/MM/YYYY HH24:MI:SS')
)
)
)
)
UNION
(
SELECT EMPBREAKS.EMPID
FROM EMPBREAKS
WHERE
(
(
TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS') BETWEEN
EMPBREAKS.STARTB AND EMPBREAKS.ENDB
)
OR
(
TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS') BETWEEN
EMPBREAKS.STARTB AND EMPBREAKS.ENDB
)
OR
(
EMPBREAKS.STARTB BETWEEN TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS'
) AND TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS')
)
OR
(
EMPBREAKS.ENDB BETWEEN TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS')
AND TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS')
)
OR
(
EMPBREAKS.FLAGCYCLIC =1
AND EMPBREAKS.DAYWEEKINDEX = 4
AND
(
TO_DATE(TO_CHAR(EMPBREAKS.STARTB,'HH24:MI:SS'),'HH24:MI:SS') BETWEEN
TO_DATE('11:00:00', 'HH24:MI:SS') AND TO_DATE('12:00:00', 'HH24:MI:SS')
)
)
OR
(
EMPBREAKS.FLAGCYCLIC =1
AND EMPBREAKS.DAYWEEKINDEX = 4
AND
(
TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'),'HH24:MI:SS') BETWEEN TO_DATE(
'11:00:00', 'HH24:MI:SS') AND TO_DATE('12:00:00', 'HH24:MI:SS')
)
)
OR
(
EMPBREAKS.FLAGCYCLIC =1
AND EMPBREAKS.DAYWEEKINDEX = 4
AND
(
TO_DATE('11:00:00', 'HH24:MI:SS') BETWEEN TO_DATE(TO_CHAR(EMPBREAKS.STARTB,
'HH24:MI:SS'),'HH24:MI:SS') AND TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'
),'HH24:MI:SS')
)
)
OR
(
EMPBREAKS.FLAGCYCLIC =1
AND EMPBREAKS.DAYWEEKINDEX = 4
AND
(
TO_DATE('12:00:00', 'HH24:MI:SS') BETWEEN TO_DATE(TO_CHAR(EMPBREAKS.STARTB,
'HH24:MI:SS', 'HH24:MI:SS')) AND TO_DATE(TO_CHAR(EMPBREAKS.ENDB,'HH24:MI:SS'
),'HH24:MI:SS'))
)
)
)
)
UNION
(
SELECT EMPSICKVACATIONS.EMP_NO
FROM EMPSICKVACATIONS
WHERE EMPSICKVACATIONS.VDATE = TO_DATE('19/06/2017 00:00:00', 'DD/MM/YYYY HH24:MI:SS')
OR
(
EMPSICKVACATIONS.CYCLICFLAG = 1
AND EMPSICKVACATIONS.WEEKDAYINDEX = 4
)
)
);
答案 2 :(得分:1)
你错过了前几个to_date的结尾括号:
TO_DATE('29/06/2017 11:00:00', 'DD/MM/YYYY HH24:MI:SS' BETWEEN SERVICES.STARTDATE AND SERVICES.ENDDATE) or
TO_DATE('29/06/2017 12:00:00', 'DD/MM/YYYY HH24:MI:SS' BETWEEN SERVICES.STARTDATE AND SERVICES.ENDDATE) or
此外,看起来您正在尝试查看两个时段的开始日期和结束日期是否重叠 - 通常您可以使用以下方式执行此操作:
and period1.start_date <= period2.end_date
and period1.end_date >= period2.start_date
这更简单,更容易掌握,恕我直言。