list of upcoming birthday oracle plsql - database

I have a problem on my hand. I am working on an application where user wants to send the wish cards to his clients whose birthday is within user provided FROM and TO date , irrespective of the year. I.e. the search results should be on the basis of the Month and date only. e.g my input parameteres are from date: "12/05" (December 05)and To Date: "01/04" (January 04). Please help. Thanks in advance

You can use extract function of PLSQL:
extract(MONTH FROM DATE '2003-08-22') would return 8
extract(DAY FROM DATE '2003-08-22') would return 22
http://www.techonthenet.com/oracle/functions/extract.php

You should use this query condition. It selects birthdate if it is in one month interval from now. Birthdate can be from any year:
where
TO_DATE(TO_CHAR(birthdate,'dd.mm')||'.1900','DD.MM.YYYY') ,
between
TO_DATE(TO_CHAR(sysdate,'dd.mm')||'.1900','DD.MM.YYYY')
and ADD_MONTHS(TO_DATE(TO_CHAR(sysdate,'dd.mm')||'.1900','DD.MM.YYYY'),1)
If user inputs date range as for example '02/03' and '23/06' ('P1' and 'P2' in this query) then use following condition.
where
(
TO_DATE(TO_CHAR(birthdate,'dd.mm')||'.1900','DD.MM.YYYY') ,
between
TO_DATE('P1'||'.1900','DD.MM.YYYY')
and
TO_DATE('P2'||'.1900','DD.MM.YYYY')
)
OR
(
(TO_DATE('P1'||'.1900','DD.MM.YYYY')
> TO_DATE('P2'||'.1900','DD.MM.YYYY') )
and
(
TO_DATE(TO_CHAR(birthdate,'dd.mm')||'.1900','DD.MM.YYYY') ,
between
TO_DATE('P1'||'.1900','DD.MM.YYYY')
and
TO_DATE('31.12.1900','DD.MM.YYYY')
OR
TO_DATE(TO_CHAR(birthdate,'dd.mm')||'.1901','DD.MM.YYYY') ,
between
TO_DATE('01.01.1901','DD.MM.YYYY')
and
TO_DATE('P2'||'.1901','DD.MM.YYYY')
)
)

assuming you've stored DOB as a DATE lets say column = "DOB" in table PPL.
ie for the raw set:
FIRSTNAME LASTNAME DOB
-------------------------------- -------------------------------- ---------
Joe Bloggs 03-JAN-90
Jane Doe 05-JAN-40
Adam West 05-DEC-76
we get
SQL> select firstname, lastname, dob, next_bday
2 from (select firstname, lastname, dob,
3 case when to_date(to_char(dob, 'mmdd'), 'mmdd') < trunc(sysdate)
4 then add_months(to_date(to_char(dob, 'mmdd'), 'mmdd'), 12)
5 else to_date(to_char(dob, 'mmdd'), 'mmdd')
6 end next_bday
7 from ppl)
8 where next_bday < add_months(trunc(sysdate), 1);
FIRS LASTNA DOB NEXT_BDAY
---- ------ --------- ---------
Joe Bloggs 03-JAN-90 03-JAN-13
Adam West 05-DEC-76 05-DEC-12

Related

Snowflake filtering for next fiscal quarter

I've got this date column (closing_date) with fields that look like this e.g. 2023-01-20
How do I dynamically filter for only records where the date is in the next fiscal quarter?
Closing_date
Name
Order_id
2024-01-20
Joe
123
2023-01-20
Joe
456
Only the second record in the table should pull in because this fiscal quarter and year ends at the end of January.
Can I do this w/o having to update my date filter each quarter?
Some date math should do the trick:
WHERE YEAR(ADD_MONTHS(CURRENT_DATE(), 3))*10 + QUARTER(ADD_MONTHS(CURRENT_DATE, 3)) = YEAR(Closing_date)*10 + QUARTER(Closing_date)
So if we define a variable to state the first month of a finacal year, here in New Zealand it's 1st April:
[corrected: to do the cur_date_projected of current date]
set fin_month = 4; // April is the first day on NZ fin year
with data(Closing_date, Name, Order_id) as (
select * from values
('2024-01-20'::date, 'Joe', 123),
('2023-01-20'::date, 'Joe', 456)
)
select *
,dateadd(month,(-$fin_month)+1, Closing_date) as date_projected
,date_trunc('quarter', date_projected) as date_in_fin_years
,year(date_in_fin_years) || 'Q' || quarter(date_in_fin_years) as date_as_fin_str
,dateadd(month,-$fin_month+1, CURRENT_DATE) as cur_date_projected
,dateadd('quarter', 1, date_trunc('quarter', cur_date_projected)) as cur_date_in_fin_years
,year(cur_date_in_fin_years) || 'Q' || quarter(cur_date_in_fin_years) as cur_date_as_fin_str
from data
gives:
CLOSING_DATE
NAME
ORDER_ID
DATE_PROJECTED
DATE_IN_FIN_YEARS
DATE_AS_FIN_STR
CUR_DATE_PROJECTED
CUR_DATE_IN_FIN_YEARS
CUR_DATE_AS_FIN_STR
2024-01-20
Joe
123
2023-10-20
2023-10-01
2023Q4
2022-07-10
2022-10-01
2022Q4
2023-01-20
Joe
456
2022-10-20
2022-10-01
2022Q4
2022-07-10
2022-10-01
2022Q4
so if we swap to fin_month to 1, and then put those date_projected and cur_date_projected into a WHERE clause
select *
from data
where date_trunc('quarter', dateadd(month,(-$fin_month)+1, Closing_date)) = dateadd('quarter', 1, date_trunc('quarter', dateadd(month,-$fin_month+1, CURRENT_DATE)))
gives:
CLOSING_DATE
NAME
ORDER_ID
2023-01-20
Joe
456

How to consolidate rows in table for the given scenario?

Let's say I have a table
CustId Name Age Gender Business Code
1 John 24 Male Automobiles 1
2 Peter 30 Male Space 3
2 Peter 30 Male IT null
3 Kris 48 Female Infra null
I need output as follows
CustId Name Age Gender Business Code
1 John 24 Male Automobiles 1
2 Peter 30 Male Space 3
3 Kris 48 Female CodeNotAvailable null
Peter has two businesses one with code and another without code. So, the row without code is removed.
Kris has business without code, so need to display CodeNotAvailable in Business column.
We can use ROW_NUMBER() to get the row numbers and pick the row. By default, SQL Server orders NULL first. We need to use order by code desc to get the non-null value as the first row in the ROW_NUBER()
SELECT CustId,Name, Age, Gender, Business, Code
from
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY CustId ORDER BY Code desc) as rnk
FROM Table) as t
WHERE rnk = 1
;with r as (
select Custid, Name, Age, Gender,
case when code is null then 'CodeNotAvailable' else Business end as Business,
Code
from myTab
)
select max(CustId) CustId, Name, Age, Gender, Business, Code
from r
group by Name, Age, Gender, Business, Code

Total no of year fig in sql count

I have data like this
id name fromdate todate
1 abc 1993 2011
2 def 2006 2016
now i want total duration i.e how many years employee spend from 1993 to 2011 here i want to show total years spend
id name fromdate todate total_years
1 abc 1993 2011 18
2 def 2006 2016 10
query
select * from employee
Do subtract beetween todate and fromdate column:
SELECT
id,
name,
fromdate,
todate,
CASE ISNUMERIC(ISNULL(todate,'')) WHEN 0 THEN 0 ELSE CAST(todate AS INT)-CAST(fromdate AS INT) END as total_years
from employee
Your output implies that you want the following query:
select id, name, fromdate, todate,
cast(todate as int) - cast(fromdate as int) as total_years
from employee
It appears that you are storing your year columns as text. This is not a good idea, and you should use a number type instead. Actually, it would be better to store actual dates in those columns, which would make it much easier to work with.

T-SQL Dynamic Query and pivot

I have data where people have changed role mid month and want to count the activity after their new start date. Can I use the results of a table as a dynamic Query, I have a query which returns the following resultset:-
Firstname Surname StartDate
----------------------------------
Jon Smith 2015-01-01
Paul Jones 2014-07-23
...
So the query would look something like:
SELECT Firstname +' '+ surname, month, count(1) FROM dataTable
WHERE (Firstname='John' AND Surname='Smith' AND date >=2015-01-01)
OR (Firstname='Paul' AND Surname='Jones' AND date >=2014-07-23)
OR ...
but the number of 'ORs' would depend on the number of rows in the first table
Name Month Count
----------------------------------
Jon Smith 1 15
Paul Jones 1 16
Jon Smith 2 30
Paul Jones 2 25
Charlie Gu 1 52
Which I can then pivot to get
Name 1 2
--------------------------
Jon Smith 15 30
Paul Jones 16 25
Charlie Gu 52 NULL
Thanks in advance
It seems to me that Ako is right and a simple join should do the trick rather than a dynamic query.
declare #NewStartDates table
(
Firstname nvarchar(100),
Surname nvarchar(100),
StartDate date
);
insert into #NewStartDates
(Firstname, Surname, StartDate)
values (N'Jon', N'Smith', '20150101'),
(N'Paul', N'Jones', '20140723');
select d.Firstname,
d.Surname,
year(d.Date) * 100 + month(d.Date) as Period,
count(*) as ActivityCount
from dataTable as d
inner join #NewStartDates as n
on d.Firstname = n.Firstname
and d.Surname = n.Surname
and d.Date >= n.StartDate
group by d.Firstname,
d.Surname,
year(d.Date) * 100 + month(d.Date);
Please refer this - it will give you complete idea how you can get dynamic column query.Dynamic Column Generation - Pivot [SQL]

First Transaction Date and Amount and Latest Transaction Date and Amount

I created a table called 'donation'.
This table has
supporter_KEY ( member unique identifier)
first_name,
last_name,
donation_key (transaction unique identifier)
email
amount and date
Here is some data
supporter_KEY first_name last_name email donation_key (date) (amount)
37519405 ALEX LANGER alex#email.com 12447199 2011-04-14 10:38:00.000 100
37519483 Anthony Russo anthony#smail3.com 12464169 2012-07-30 14:12:00.000 125
37519656 Bert Kaplan sample1#aol.com 12460672 2011-11-25 08:08:00.000 35
37519905 Brett Graham sample2#yahoo.com 12466260 2013-01-14 10:43:00.000 100
37519939 Bruce Decker sample3#hotmail.com 12466441 2013-03-20 08:59:00.000 25
37520331 Craig Pettigrew sample4#aol.com 12464780 2012-08-28 13:52:00.000 25
37520787 Donn Schaible sample9#aol.com 12466886 2013-04-09 16:50:00.000 125
37521145 George Cooper sample43#gmail.com 12420119 2011-03-09 10:17:00.000 100
37521145 George Cooper sample43#gmail.com 12459908 2011-07-19 09:19:00.000 50
I am trying in one query to pull the latest transaction amount and date and in the other query to pull the first transaction date and amount
Here is each query:
Query for first transaction date and amount:
SELECT supporter_KEY,
first_name,
last_name,
email,
donation_key,
MIN(date) as first_transaction_date,
MIN(Amount) as first_transaction_amount
FROM donation
WHERE supporter_KEY > '1'
GROUP BY supporter_KEY,first_name,last_name,email,donation_key
And the Query for the latest transaction date and amount:
SELECT supporter_KEY ,
first_name ,
last_name,
email,
donation_key ,
MAX(date) as latest_transaction_date,
MAX(Amount) as latest_transaction_amount
WHERE supporter_KEY > '1'
FROM donation
GROUP BY supporter_KEY,first_name,last_name,email,donation_key
I just want to make sure I am on the right track and I would also like to pull the largest Trx Date & Amount (?).
Can someone help me out?
The queries are essentially the same. Here's the query for the first transaction, to get the latest transaction change the MIN in the subquery to MAX. Note that this will only select the first row (with unknown sorting) if there is more than one row with the same date.
SELECT TOP 1
supporter_KEY,
first_name,
last_name,
email,
donation_key,
date as first_transaction_date,
amount as first_transaction_amount
FROM
donation
WHERE
date = (SELECT MIN(date) FROM donation)

Resources