Skip to main content

Finding Leap Year using SQL



Before we start writing a statement to find a Leap Year, let us first understand what is a Leap Year.

According to Gregorian Calendar each year consists of 365 day. In reality Earth takes approximately 365.242375 days to circle once around the Sun.

As the Gregorian calendar has only 365 days in a year, so if we didn't add a day on February 29 nearly every 4 years, we would lose almost six hours off our calendar every year. After only 100 years, our calendar would be off by approximately 24 days!

Lets look at it in more details,

Because the Earth rotates about 365.242375 times a year ...

... but a normal year is 365 days, ...

... so something has to be done to "catch up" the extra 0.242375 days a year.

So every 4th year we add an extra day (the 29th of February), which makes 365.25 days a year. This is fairly close, but is wrong by about 1 day every 100 years.

So every 100 years we don't have a leap year, and that results in 365.24 days per year (1 day less in 100 year = -0.01 days per year). Closer, but still not accurate enough!

So another rule says that every 400 years is a leap year again. This gets us 365.2425 days per year (1 day regained every 400 years = 0.0025 days per year), which is close enough to 365.242375 not to matter much.

So this is why we have Leap Year once every 4 years.

According to Gregorian calendar 3 criteria must be taken into account to identify leap years:

1. The year is evenly divisible by 4;
2. If the year can be evenly divided by 100, it is NOT a leap year, unless;
3. The year is also evenly divisible by 400. Then it is a leap year.

This means that 2000 and 2400 are leap years, while 1800, 1900, 2100, 2200, 2300 and 2500 are NOT leap years.

The year 2000 was somewhat special as it was the first instance when the third criterion was used in most parts of the world since the transition from the Julian to the Gregorian Calendar.


Now its time for an SQL which can check all 3 conditions.

Following example is with CASE conditional Expression,

SELECT 
CASE WHEN (mod(&&a,4) = 0 and mod(&a,100) <> 0) OR
(mod(&a,4) = 0 and mod(&a,100) = 0 and mod(&a,400) = 0)
THEN '&&a is a Leap Year'
ELSE '&a is not a Leap Year' END
FROM dual;

Following example is without CASE,

SELECT '&&a is a Leap Year'
FROM dual
WHERE (mod(&a,4) = 0 and mod(&a,100) <> 0)
OR
(mod(&a,4) = 0 and mod(&a,100) = 0 and mod(&a,400) = 0);





Comments

chandra patil said…
Hi Mithun,
When we execute this statement for second time it is directly giving the same output of the previous input i.e once the variable given a value or initialized we need to take another variable name and execute the statement for another input; Is there any solution that we can give different input for the same variable.
Regards
Chandra
Mithun said…
Hi Chandra,

Once you execute the query to set the variable again, execute the command below,

undef a
Unknown said…
hello mithun..
I need a query to display my current age .... so my birth date is 16th sep 1988...
Thank you..
This comment has been removed by the author.
select trunc(months_between(sysdate,'16-sep-1988')/12) years from dual

Popular posts from this blog

SQL Interview Questions on Subqueries

SUB Queries:
1. List the employees working in research department 2. List employees who are located in New York and Chicago
3. Display the department name in which ANALYSTS are working
4. Display employees who are reporting to JONES
5. Display all the employees who are reporting to Jones Manager
6. Display all the managers in SALES and ACCOUNTING department
7. Display all the employee names in Research and Sales Department who are having at least 1 person reporting to them
8. Display all employees who do not have any reportees
9. List employees who are having at least 2 reporting
10. List the department names which are having more than 5 employees
11. List department name having at-least 3 salesman
12. List employees from research and accounting having at-least 2 reporting
13. Display second max salary
14. Display 4th max salary
15. Display 5th max salary  -- Answer for nth Max Salary
Co-Related Subqueries:
16. Write a query to get 4th max salary from EMP table
17. Write a query to get 2nd…

'Linux-x86_64 Error: 28: No space left on device' While trying to start the database -- Error

SQL> startup mount pfile='/tmp/initdlfasp12.ora'
ORA-27102: out of memory
Linux-x86_64 Error: 28: No space left on device


This as you can see is on Linux x86 with 64 bit processor. We got this error after we changed SGA on 10gR2 database. So was sure that this is something to do with the OS.

Parameters to check for this are shmall.

shmall is the total amount of shared memory, in pages, that the system can use at one time.

$cat /proc/sys/kernel/shmmax
53687091200

$ getconf PAGE_SIZE
4096

As per Oracle SHMALL should be set to the total amount of physical RAM divided by page size.

Our system has 64GB memory, so change kernel.shmall = 1024 * 1024 * 1024 * 64 / 4096 = 16777216


Once this value is calculated you can modify Linux system configuration file directly.

$ su - root
vi /etc/sysctl.conf file:
kernel.shmall=16777216

and

# sysctl -p

Once this is done the database was started without any problem.

Answers for SUB Queries

1. SQL> select empno, ename from emp where deptno=(select deptno from dept where dname='RESEARCH');


2. SQL> select empno, ename from emp where deptno in (select deptno from dept where loc in ('NEW YORK','CHICAGO'));

3. SQL> select dname from dept where deptno in ( select deptno from emp where job ='ANALYST');

4. SQL> select empno, ename, mgr from emp where mgr = (select empno from emp where ename='JONES');

5. SQL> select empno, ename, mgr from emp where mgr = (select mgr from emp where ename='JONES')

6. SQL> select empno, ename, job from emp where deptno in ( select deptno from dept where dname in ('SALES','ACCOUNTING'))

7. SQL> select empno, ename, job from emp where deptno in ( select deptno from dept where dname in ('SALES','RESEARCH')) and empno in (select mgr from emp)

8. SQL> select empno, ename from emp where empno not in ( select mgr from emp where mgr is not null)

9. select…