SQL Select all entries from last two months - sql

I would like to select dynamically all entries from last two months, and without entering date range in my query.
Here is my simple code:
SELECT Customer_Name, Date FROM table_Customer; all data between last two month
Thanks in advance for your help
SELECT
ME.FullName,
R.RuleDefaultName,
PR.ObjectName,
PR.CounterName,
P.DateTime,
P.SampleCount,
P.MinValue,
P.MaxValue,
P.AverageValue,
P.StandardDeviation
FROM
Perf.vPerfHourly P
INNER JOIN vManagedEntity ME ON
P.ManagedEntityRowId = ME.ManagedEntityRowId
INNER JOIN vPerformanceRuleInstance PRI ON
P.PerformanceRuleInstanceRowId = PRI.PerformanceRuleInstanceRowId
INNER JOIN vPerformanceRule PR ON
PRI.RuleRowId = PR.RuleRowId
INNER JOIN vRule R ON
PRI.RuleRowId = R.RuleRowId

SELECT Customer_Name, Dt
FROM table_Customer
where dt >= dateadd(day, -60, getdate())
Or
SELECT Customer_Name, Dt
FROM table_Customer
where dt >= dateadd(month, -2, getdate())
You should make sure not to use reserved keywords as column names.
Make sure you replace dt with the appropriate date column. The solution assumes you would need the previous 2 months data starting with the current date.

Select *
From Customers
Where
OrderDate between Dateadd(M,-2,OrderDate) And Getdate()

Related

How to add a set of dates for each category in a dimension?

I have data that looks like this where there is a monthly count of a particular animal for each month. By default, it aggregates in the month where there is data.
However, I would like to like to have a default set of dates for each animal up to the current month date with 0 if there's no data. Desired Result -
Is there a way to handle with a on sql server and not in Excel?
Much appreciated in advance.
You can generate the months you want using a numbers table or recursive CTE (or calendar table). Then cross join with the animals to generate the rows and use left join to bring in the existing data:
with dates as (
select min(date) as dte
from t
union all
select dateadd(month, 1 dte)
from dates
where dte < getdate()
)
select a.animal, d.dte, coalesce(t.monthly_count, 0) as monthly_count
from dates d cross join
(select distinct animal from t) a left join
data t
on t.date = d.dte and t.animal = a.animal
order by a.animal, d.dte;

SQL if statement for date range

Hi I was needing help with the syntax to add a condition where the current date is retrieved if today is after the 5th of each month but if its between the 1st to the 5th then it should retrieve the month before this month. Is it something you can help with please? Below is how my query is structured.
Select *
FROM table1
left join table2
on e.ENTITY_NBR = d.entity_nbr
and cast(getdate() as date) between MONTH_BEGIN_DATE and MONTH_END_DATE
Select *,
CASE WHEN day(GETDATE()) > 5 THEN GETDATE()
ELSE DATEADD(month,-1,getdate()) END as date
FROM table1
left join table2
on e.ENTITY_NBR = d.entity_nbr
and cast(getdate() as date) between MONTH_BEGIN_DATE and MONTH_END_DATE
Based on a vague description of your problem this is the best I can write.
If you simply want to include todays date (or the same date from last month if it's currently the 5th or earlier in the current month), then this can be done in your SELECT clause:
select
case
when datepart(day,getdate()) <= 5
then dateadd(month,-1,getdate())
else getdate()
end
If you want to actually use this date to compare to some field in your dataset, then you can include this same case expression in your WHERE clause.
where the current date is retrieved if today is after the 5th of each month but if its between the 1st to the 5th then it should retrieve the month before this month.
Based on this description, you want something like this:
select *
from table1 e left join
table2 d
on e.ENTITY_NBR = d.entity_nbr and
(day(getdate() > 5 and datediff(month, d.date_col, getdate()) = 0 or
day(getdate() <= 5 and datediff(month, d.date_col, getdate()) = 1)
)

SQL add max and second max date to query that includes with

Posted a question yesterday about SQL append distinct values from two columns and two tables that resulted in the following code:
with cte1 as
(Select Distinct "Tra.".cus_outnum As "account number" from table1 "Tra." Where "Tra.".invdat >= DATEADD(year, -1, GETDATE())
union
Select Distinct "Sal.".outnum As "account number" From table2 "Sal." Where "Sal.".deldat>= DATEADD(year, -1, GETDATE()))
,cte2 as
(Select Distinct "Tra.".artnum As "article number" from tabel1 “Tra.” Where "Tra.".invdat >= DATEADD(year, -1, GETDATE())
union
Select Distinct ISNULL("Sal.".org_artnum, "Sal.".artnum) As "article number" From table2 "Sal." Where "Sal.".deldat>= DATEADD(year, -1, GETDATE()))
Select * from cte1 cross join cte2
It produces a table with all distinct combination of account numbers and article numbers from two different tables where orders are done later than one year ago.
Next object that I'm struggling with is to include the latest and second latest purchase date in two new columns. If no purchase is done for any combination of account and article, it should result in a null(blank) value. And the latest/second latest date (i.e max date) should come from either one or the other of the tables. End result should be along the lines of:
<table><tbody><tr><th>Account</th><th>Article</th><th>Latest Date</th><th>Second to latest Date</th></tr><tr><td>1</td><td>1</td><td>26.06.2018</td><td>13.03.2018</td></tr><tr><td>1</td><td>2</td><td>15.05.2018</td><td>Blank (no purchase)</td></tr><tr><td>2</td><td>1</td><td>23.06.2018</td><td>30.06.2017</td></tr><tr><td>2</td><td>2</td><td>Blank (no purchase)</td><td>Blank (no purchase)</td></tr></tbody></table>
Many thanks for all the help, it is much appreciated!
Partially pseudeo. To get more detailed help please offer a db-fiddle.
SELECT
a.Account as Account,
b.Article as Article,
(<SUBSELECT> MAX(DATE) FROM ... WHERE ... ) as LatestDate,
(<SUBSELECT> MAX(DATE) FROM ... WHERE ... < LatestDate ) as 'SecondToLatestDate')
FROM
accounts a JOIN articles b
+ some IFNULL's

Summing up columns from two different tables

I have two different tables FirewallLog and ProxyLog. There is no relation between these two tables. They have four common fields :
LogTime ClientIP BytesSent BytesRec
I need to Calculate the total usage of a particular ClientIP for each day over a period of time (like last month) and display it like below:
Date TotalUsage
2/12 125
2/13 145
2/14 0
. .
. .
3/11 150
3/12 125
TotalUsage is SUM(FirewallLog.BytesSent + FirewallLog.BytesRec) + SUM(ProxyLog.BytesSent + ProxyLog.BytesRec) for that IP. I have to show Zero if there is no usage (no record) for that day.
I need to find the fastest solution to this problem. Any Ideas?
First, create a Calendar table. One that has, at the very least, an id column and a calendar_date column, and fill it with dates covering every day of every year you can ever be interested in . (You'll find that you'll add flags for weekends, bankholidays and all sorts of other useful meta-data about dates.)
Then you can LEFT JOIN on to that table, after combining your two tables with a UNION.
SELECT
CALENDAR.calendar_date,
JOINT_LOG.ClientIP,
ISNULL(SUM(JOINT_LOG.BytesSent + JOINT_LOG.BytesRec), 0) AS TotalBytes
FROM
CALENDAR
LEFT JOIN
(
SELECT LogTime, ClientIP, BytesSent, BytesRec FROM FirewallLog
UNION ALL
SELECT LogTime, ClientIP, BytesSent, BytesRec FROM ProxyLog
)
AS JOINT_LOG
ON JOINT_LOG.LogTime >= CALENDAR.calendar_date
AND JOINT_LOG.LogTime < CALENDAR.calendar_date+1
WHERE
CALENDAR.calendar_date >= #start_date
AND CALENDAR.calendar_date < #cease_date
GROUP BY
CALENDAR.calendar_date,
JOINT_LOG.ClientIP
SQL Server is very good at optimising this type of UNION ALL query. Assuming that you have appropriate indexes.
If you don't have a calendar table, you can create one using a recursive CTE:
declare #startdate date = '2013-02-01';
declare #enddate date = '2013-03-01';
with dates as (
select #startdate as thedate
union all
select dateadd(day, 1, thedate)
from dates
where thedate < #enddate
)
select driver.thedate, driver.ClientIP,
coalesce(fwl.FWBytes, 0) + coalesce(pl.PLBytes, 0) as TotalBytes
from (select d.thedate, fwl.ClientIP
from dates d cross join
(select distinct ClientIP from FirewallLog) fwl
) driver left outer join
(select cast(fwl.logtime as date) as thedate,
SUM(fwl.BytesSent + fwl.BytesRec) as FWBytes
from FirewallLog fwl
group by cast(fwl.logtime as date)
) fwl
on driver.thedate = fwl.thedate and driver.clientIP = fwl.ClientIP left outer join
(select cast(pl.logtime as date) as thedate,
SUM(pl.BytesSent + pl.BytesRec) as PLBytes
from ProxyLog pl
group by cast(pl.logtime as date)
) pl
on driver.thedate = pl.thedate and driver.ClientIP = pl.ClientIP
This uses a driver table that generates all the combinations of IP and date, which it then uses for joining to the summarized table. This formulation assumes that the "FirewallLog" contains all the "ClientIp"s of interest.
This also breaks out the two values, in case you also want to include them (to see which is contributing more bytes to the total, for instance).
I would recommend creating a Dates Lookup table if that is an option. Create the table once and then you can use it as often as needed. If not, you'll need to look into creating a Recursive CTE to act as the Dates table (easy enough -- look on stackoverflow for examples).
Select d.date,
results.ClientIp
Sum(results.bytes)
From YourDateLookupTable d
Left Join (
Select ClientIp, logtime, BytesSent + BytesRec bytes From FirewallLog
Union All
Select ClientIp, logtime, BytesSent + BytesRec bytes From ProxyLog
) results On d.date = results.logtime
Group By d.date,
results.ClientIp
This assumes the logtime and date data types are the same. If logtime is a date time, you'll need to convert it to a date.

How to count records for each day in a range (including days without records)

I'm trying to refine this question a little since I didn't really ask correctly last time. I am essentially doing this query:
Select count(orders)
From Orders_Table
Where Order_Open_Date<=To_Date('##/##/####','MM/DD/YYYY')
and Order_Close_Date>=To_Date('##/##/####','MM/DD/YYYY')
Where ##/##/#### is the same day. In essence this query is designed to find the number of 'open' orders on any given day. The only problem is I'm wanting to do this for each day of a year or more. I think if I knew how to define the ##/##/#### as a variable and then grouped the count by that variable then I could get this to work but I'm not sure how to do that-or there may be another way as well. I am currently using Oracle SQL on SQL developer. Thanks for any input.
You could use a "row generator" technique like this (edited for Hogan's comments):
Select RG.Day,
count(orders)
From Orders_Table,
(SELECT trunc(SYSDATE) - ROWNUM as Day
FROM (SELECT 1 dummy FROM dual)
CONNECT BY LEVEL <= 365
) RG
Where RG.Day <=To_Date('##/##/####','MM/DD/YYYY')
and RG.Day >=To_Date('##/##/####','MM/DD/YYYY')
and Order_Open_Date(+) <= RG.Day
and Order_Close_Date(+) >= RG.Day - 1
Group by RG.Day
Order by RG.Day
This should list each day of the previous year with the corresponding number of orders
Lets say you had a table datelist with a column adate
aDate
1/1/2012
1/2/2012
1/3/2012
Now you join that to your table
Select *
From Orders_Table
join datelist on Order_Open_Date<=adate and Order_Close_Date>=adate
This gives you a list of all the orders you care about, now you group by and count
Select aDate, count(*)
From Orders_Table
join datelist on Order_Open_Date<=adate and Order_Close_Date>=adate
group by adate
If you want to pass in a parameters then just generate the dates with a recursive cte
with datelist as
(
select #startdate as adate
UNION ALL
select adate + 1
from datelist
where (adate + 1) <= #lastdate
)
Select aDate, count(*)
From Orders_Table
join datelist on Order_Open_Date<=adate and Order_Close_Date>=adate
group by adate
NOTE: I don't have an Oracle DB to test on so I might have some syntax wrong for this platform, but you get the idea.
NOTE2: If you want all dates listed with 0 for those that have nothing use this as your select statement:
Select aDate, count(Order_Open_Date)
From Orders_Table
left join datelist on Order_Open_Date<=adate and Order_Close_Date>=adate
group by adate
If you want only one day you can query using TRUNC like this
select count(orders)
From orders_table
where trunc(order_open_date) = to_date('14/05/2012','dd/mm/yyyy')