简体   繁体   中英

Date Difference and ORA-00937 - not a single-group group function

I am trying to add two tables and get the total days from two dates. But having the following simple issue: not a single-group group function .

This is what I've tried so far:

SELECT COUNT(status) AS "Present Days",  
       (SELECT TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY')) 
        FROM attendance m
             INNER JOIN EMP_OFFICIAL k 
             ON k.EMPNO = m.EMPNO 
        WHERE m.empno='EMP00254' 
        AND m.status='P') AS "Total Days" 
FROM attendance 
WHERE empno = 'EMP00254' 
AND status = 'P';

Can I get the days without using the DUAL?

First off, that subquery is most likely not scalar (it looks like you're assuming multiple rows can come from the attendance table) and second, it contains an unnecessary join..

What I would do instead is something like:

select count(*) as "Present Days",
       to_date('01/10/2018', 'mm/dd/yyyy') - k.joining_date "Total Days"
from   attendance a
       inner join emp_official k on a.empno = k.empno
where  a.empno = 'EMP00254'
and    a.status = 'P'
group by to_date('01/10/2018', 'mm/dd/yyyy') - k.joining_date;

This does assume that the k.joining_date column is of DATE datatype and that 'k.empno' is a unique column.

If there is only one row in the EMP_OFFICIAL table for each employee then you could do:

SELECT COUNT(a.status) AS "Present Days",  
       TRUNC( SYSDATE ) - TRUNC( MIN( k.joining_date ) ) AS "Total Days" 
FROM   attendance a
       RIGHT OUTER JOIN EMP_OFFICIAL k
       ON ( k.EMPNO = a.EMPNO )
WHERE  a.empno = 'EMP00254' 
WHERE  a.status = 'P';

or you could do the aggregation in a sub-query:

SELECT a."Present Days",  
       TRUNC( SYSDATE ) - TRUNC( k.joining_date ) AS "Total Days" 
FROM   (
         SELECT EMPNO,
                COUNT( status ) AS "Present Days"
         FROM   attendance
         WHERE  EMPNO = 'EMP00254'
         AND    status = 'P'
         GROUP BY EMPNO
       ) a
       RIGHT OUTER JOIN EMP_OFFICIAL k
       ON ( k.EMPNO = a.EMPNO )
WHERE  k.EMPNO = 'EMP00254';

Or you could use UNION ALL to query the two tables and have the result in two rows (rather than two columns):

SELECT 'Present Days' As type,
       COUNT(status)  AS Days
FROM   attendance
WHERE  empno = 'EMP00254' 
WHERE  status = 'P'
UNION ALL
SELECT 'Total Days',
       TRUNC( SYSDATE ) - TRUNC( joining_date )
FROM   EMP_OFFICIAL
WHERE  empno = 'EMP00254';

Either remove COUNT(status) AS "Present Days" part and SELECT inside paranthesis :

SELECT (TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY')) "time difference" FROM attendance m
INNER JOIN EMP_OFFICIAL k ON k.EMPNO = m.EMPNO where m.empno='EMP00254' and m.status='P') AS "Total Days" 
 FROM attendance where empno = 'EMP00254' and status = 'P';

OR

use the following (add GROUP BY expression at the end of sql):

SELECT COUNT(status) AS "Present Days",  
(TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY')) "time difference" FROM attendance m
INNER JOIN EMP_OFFICIAL k ON k.EMPNO = m.EMPNO where m.empno='EMP00254' and m.status='P') AS "Total Days" 
 FROM attendance where empno = 'EMP00254' and status = 'P'
GROUP BY (TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY'));

Since , groupped and non-groupped items can not be used together.

By the way, you don't need to use dual in your inline select statement like ( SELECT TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY') FROM DUAL ) , just ( TRUNC(TO_DATE('01/10/2018', 'MM/DD/YYYY') - TO_DATE(k.JOINING_DATE, 'MM/DD/YYYY')) is enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM