I am new to SQL Server world. I have a table as below:
alert_id | create_date | Status
---------+-------------+---------
1231 | 4/15/2017 | Open
1232 | 4/15/2017 | Open
1234 | 4/15/2017 | Closed
1235 | 4/16/2017 | Open
All of these alerts should be closed in 30 days. I need to get a forecast report which shows how many alerts are open for past 30 days.
I would like to write a select query whose output would be 2 columns. First would be Date and 2nd would be count. The date column should display all the dates for next 30 days and Count column should display the number of records which are due to expire on that day. Something like below would work. Please assist.
date | Count
----------+---------
5/15/2017 | 2
5/16/2017 | 3
5/17/2017 | 0
5/18/2017 | 0
.
.
.
6/14/2017 | 0
This is a job for GROUP BY and date arithmetic. In MySQL:
SELECT DATE(create_date) + INTERVAL 30 DAY expire_date, COUNT(*) num
FROM tbl
WHERE status = 'Open'
GROUP BY DATE(create_date)
DATE(create_date) + INTERVAL 30 DAY gets you the create date values with thirty days added.
GROUP BY(create_date) groups your data by values of your create date, truncated to midnight.
And, COUNT(*) goes with GROUP BY to tell you how many records in each group.
Edit In recent versions of SQL Server (MS)
SELECT DATEADD(day, 30, CAST(create_date AS DATE)) expire_date, COUNT(*) num
FROM tbl
WHERE status = 'Open'
GROUP BY CAST(create_date AS DATE)
Notice, please, that date arithmetic varies between make and model of SQL server software. That's why you get hassled by Stack Overflow users in comments when you use more than one tag like [oracle] [mysql] [sql-server] on your questions.
Cool, huh? You should read up on aggregate queries, sometimes called summary queries.
You're not going to get the missing dates with zeros by them. That's quite a bit harder to do with SQL.
Related
I'm asking for your kindly explanation on this.
I have a Calendar table, where each day is having a row. Also I have a table with backup results, where the date and time of backup start is stored.
My goal is to have this result:
date of month | serverid | datetime of backup | result | note (not in table, for info only)
2022-02-02 | 11 | 2022-02-02 19:00 | OK | backup was successful
2022-02-03 | NULL | NULL | NULL | backup was not even start
2022-02-04 | 11 | 2022-02-04 19:00 | FAILED | backup started but error occured
I tried LEFT OUTER JOIN and OUTER APPLY.
LEFT OUTER JOIN is not returning the null lines where backup is not started
OUTER APPLY is working much better, but when I filter results by Year, Month (from calendar table) and serverid, NULL lines are gone also.
So my goal is to select ALL lines from calendar table in the specified month and year and assign the results to them by the backup start datetime column to see the days where the backup was not started also.
Can you please point me at right way?
Best Regards, Jan
Example of queries:
SELECT [SqlDt], [Year], [Month], A.*
FROM [portal].[dbo].[Calendar] C OUTER APPLY
(SELECT *
FROM [DS-Backup] D
WHERE [C].[SqlDt] = CAST(D .VersionDate AS Date)) A
SELECT dbo.Calendar.SqlDt, dbo.Calendar.Year, dbo.Calendar.Month, dbo.[DS-Backup].EID, dbo.[DS-Backup].VersionDate, dbo.[DS-Backup].VersionStatus
FROM dbo.Calendar LEFT OUTER JOIN
dbo.[DS-Backup] ON dbo.Calendar.SqlDt = CAST(dbo.[DS-Backup].VersionDate AS Date)
Thank you all for useful commnets, I was not filter the table with backup results before join.
Now it is working the way I want:
SELECT [SqlDt],[Year],[Month],[Backups].*
FROM [portal].[dbo].[Calendar]
LEFT JOIN ( SELECT * FROM [portal].[dbo].[DS-WindowsServerBackup] WHERE EID=11) as Backups
ON Calendar.SqlDt = CAST([Backups].[VersionDate] as Date)
My table:
Items | Price | UpdateAt
1 | 2000 | 02/02/2015
2 | 4000 | 06/04/2015
3 | 2150 | 07/05/2015
4 | 1800 | 07/05/2015
5 | 5540 | 08/16/2015
4 | 1700 | 12/24/2015
5 | 5200 | 12/26/2015
2 | 3900 | 01/01/2016
4 | 2000 | 06/14/2016
As you can see, this is a table that keeps items' price as well as their old price before the last update.
Now I need to find the rows which :
UpdateAt is more than 1 year ago from now
Must have updated price at least once ever since
Aren't the most up-to-date price
So with those conditions, the result from the above table should be :
Items | Price | UpdateAt
2 | 4000 | 06/04/2015
4 | 1800 | 07/05/2015
I can achieve what I need with this
Declare #LastUpdate date set #LastUpdate = DATEADD(YEAER, -1, GETDATE())
select Items, UpdateAt from ITEM_PRICE where Items in (
select Items from (
select Items, count(Items) as C from ITEM_PRICE group by Items) T
where T.C > 1)
and UpdateAt < #LastUpdate
But since I am still a newbie in sqlserver, and this need to be done in vb.net, passing along that query with lots of select in it seems sloppy and hard to maintain.
So, I would like to ask if anyone can give me a simpler solution ?
Sorry, i edited my question as I need one more condition to be met after trying #Tim Biegeleisen's answer, which is indeed the correct one for the question before edit. And I can't figure this out anymore.
Why I need all those condition, it's because I'm having to clean up the table: Clearing off the data that's older than 1 year, while still keeping the most up-to-date item price.
In my answer below, I use a subquery to identify all items which appear in the table during the last year. This is the requirement of having an updated price "at least once ever since." In the outer query, I restrict to only records which are older than one year from now, which is the other part of the requirement. An INNER JOIN is used, because we want to filter off records which do not meet both criteria.
SELECT t1.Items, t1.Price, t1.UpdateAt
FROM ITEM_PRICE t1
INNER JOIN
(
SELECT DISTINCT Items
FROM ITEM_PRICE
WHERE UpdateAt > DATEADD(year, -1, GETDATE())
) t2
ON t1.Items = t2.Items
WHERE t1.UpdateAt <= DATEADD(year, -1, GETDATE())
Once again, SQL Fiddle is having problems simulating SQL Server. But I went ahead and created a Fiddle in MySQL, which looks nearly identical to my SQL Server answer. You can verify that the logic and output are correct.
SQLFiddle
I have a scenario where I the dimension has a series of date / time members but instead I want to show it grouped to the day, how do I do that?
Example cube query:
select {[Measures].[Count]} on columns,
[Date].[Date].[Date] on rows
from [Cube]
and this query returns:
| count
2014-03-03 15:50:24.000 | 1
2014-03-03 16:05:10.000 | 1
2014-03-03 16:05:21.000 | 1
2014-03-02 16:30:13.000 | 1
I want to be able to show
| count
2014-03-03 | 3
2014-03-02 | 1
I'm using Microsoft Analysis Services 2008 R2 and the MDX queries for that
Maybe this is a little similar to what you're trying to achieve:
WITH
MEMBER [Measures].[countDays] AS
Count((EXISTING [Date].[Calendar].[Date]))
SELECT
{[Measures].[countDays]} ON COLUMNS
,[Date].[Calendar].[Month] ON ROWS
FROM [Adventure Works];
It returns the following:
I have written a HQL query, which creates a statistic report, with daily counts.
select cast(time as date), count(*) from table
group by cast(time as date)
The Eclipse Hibernate plugin reports a dynamic SQL preview, which is when run, works properly. The generated query looks like this:
select cast(time as date) as col_0_0_, count(*) as col_1_0_
from TABLE table0_ group by cast(time as date)
Everything is fine up until now, however when I run the HQL query, the date I get back is wrong (it is offset by exactly two days). This really looks like the same issue as in this question, however the hotfix does not solve it. I am using the latest Microsoft SQL Server driver, JDK 7 and Hibernate 4.3.8.
Have anyone encountered this issue?
These are my actual results:
Received output
Date | Count
--------------+---------
2015-03-01 | 1
2015-03-02 | 43
2015-03-03 | 29
Expected output
Date | Count
--------------+---------
2015-03-03 | 1
2015-03-04 | 43
2015-03-05 | 29
I have also noted, that when I cast the date to a string, it works properly, so
cast(cast(time as date) as text)
yields correct results.
I'm currently trying to replicate an old report that used to produce a rolling sum of collections. However it wasn't a standard month on month. Here is screen shot of the excel based report.
The blue section is based on a simple query and gives the dataset used to start(EXAMPLE):
SELECT COUNT(AccountNo) AS Number, SUM(Balance) AS Value, DATENAME(MM,DateOpened) AS Month, DATEPART(Y,DateOpened) AS Year FROM tblAccounts
GROUP BY DATENAME(MM,DateOpened), DATEPART(Y,DateOpened)
The tables are very basic :
AccountNo | Balance | DateOpened
12345 | 1245.55 | 01/01/2015
I'm struggling to get it to work out the months on a rolling basis, so Month 1 for Apr 2011 will be the first month for those files (payments in April), month 2 would be payments in May for the accounts opened in April (I hope that is clear).
So this means Month 1 for April would be April, and Month 1 for Nov would be Nov. Payments are stored in a table tblPayments
AccountNo | DatePayment | PaymentValue
12345 | 02/02/2015 | 15.99
Please ask if I haven't been clear enough
Assuming you have a column called "DatePayment", you should simply do something like this:
SELECT COUNT(AccountNo) AS Number, SUM(Balance) AS Value,
DATENAME(MM,DateOpened) AS Month, DATEPART(Y,DateOpened) AS Year,
DATEDIFF(MONTH, DateOpened, DatePayment) AS MonthN
FROM [...]
GROUP BY DATENAME(MM,DateOpened), DATEPART(Y,DateOpened),
DATEDIFF(MONTH, DateOpened, DatePayment)
The DATEDIFF simply counts the months between the date the account was opened and the date of the payment. Note that you might want to change the DateOpened to always be the 1st of the month in the DATEDIFF calculation.
In the FROM [...] part of your query, you will need a join between your Payments-table and the table holding your accounts, in order to be able to compare DateOpened with DatePayment. You should join them on the AccountNo-column. This looks something like this:
FROM Accounts INNER JOIN Payments ON Accounts.AccountNo = Payments.AccountNo
After doing this, you will need to make sure that all references to columns that exist in both tables are fully qualified. This means that COUNT(AccountNo) should be changed to COUNT(Accounts.AccountNo), etc.