get query grouped by date - sql

I have these table:
server ocurrences date
A 122 20200101
B 1 20200101
C 15 20200101
............
I'm tring to get these result:
A;B;C
20200101 122;1;15
I make these query:
select server, ocurrences, date FROM NET_REPORT
where to_char(date,'YYYYMMDD') >= '20200101'
AND server IN ('A','B','C') GROUP BY date, server,ocurrences ORDER BY date,server;
But I can't get what I want.
Could you help me please?
Thanks

I think you want string_agg() or array_agg(). I strongly recommend the latter:
select date, array_agg(server) as servers,
array_agg(ocurrences) as occurrences
from net_report
where date >= '2020-01-01' and
date < '2020-01-02' and
server in ('des', 'pre', 'prod')
group by date
order by date;

Related

Return ID if sum of value is between two possible date ranges, and output which date range it came from?

I have a table that has a similar structure as this:
UserID
Amount
Date
123
50
01/01/2021
234
105
02/01/2021
123
60
01/15/2021
345
70
01/15/2021
456
110
12/31/2020
345
50
02/15/2020
I have two date ranges, 01/01/2021 - 01/31/2021 and 02/01/2021 - 02/28/2021. I want to get a list of UserIDs if they had total amount >= 100 within these date ranges, and to specify which date range it came from.
So in this example, I'd like an output like this:
UserID
Total Amount
Date Range
123
110
January
234
105
February
User ID 345 and 456 would not be included since their total amounts only reached >= 100 outside of the date ranges.
In my code, I'm not sure how to exclude UserID 345 since technically they have an amount >= 100 coming from dates in both ranges and not just one single range.
I'm having troubles with only summing if it's within the date range and I'm not sure how to specify from which date range it's coming from:
SELECT
UserID
,SUM(amount)
FROM table
WHERE
date BETWEEN '01-01-2021' AND '01-31-2021' OR
date BETWEEN '02-01-2021' AND '02-28-2021'
GROUP BY
UserID
HAVING SUM(amount) >= 100
You could use CROSS APPLY to calculate the date range, and then group by it.
But in this instance, it appears you are just using whole months, so we can just use DATENAME.
Side notes:
You should not use mm-dd-yyyy format for date literals
You can combine your two periods together in this instance, I have not done so to leave you the option of disjoint periods.
SELECT t.UserID,
SUM(t.amount),
Month = DATENAME(month, t.date)
FROM table t
WHERE t.Date BETWEEN '2021-01-01' AND '2021-01-31' OR
t.date BETWEEN '2021-02-01' AND '2021-02-28'
GROUP BY UserId, DATENAME(month, t.date);
NOTE: if your dates are actually datetime values then your filter is wrong. Instead you must use a half open interval:
WHERE t.Date >= '2021-01-01' AND t.Date < '2021-02-01' OR
t.date >= '2021-02-01' AND t.Date < '2021-03-01'
If your date ranges are months, you can join to the ranges and then aggregate by user:
select min(range_name), user_name, sum(amount)
from t join
(values ('2021-01-01', '2021-01-31', 'January'),
('2021-02-01', '2021-02-28', 'February')
) v(range_start, range_end, range_name)
on t.date >= v.range_start and t.date <= v.range_end
group by userid
having count(distinct range_name) = 1 and
sum(amount) > 100;
The having clause limits the results both by the number of ranges and by the amount.
If you just wants months between particular dates, I would simplify this to:
select datepart(month, min(date)), userid, sum(amount)
from t
where date >= '2021-01-01' and date < '2021-03-01'
group by userid
having count(distinct month(date)) = 1 and
sum(amount) > 100;

SQL date (specific date)

I want to get the list of offices name that was working for us before 2015-01-01 and after 2016-01-01 but not between 2015-01-01 and 2016-01-01.
If try to put NOT BETWEEN then it will basically give me the result excluding that two dates.can somebody solve this ?
select distinct office_name
from history
where date not between '01-jan-2015' and '01-jan-2016'
I think you want aggregation:
select office_name
from history
group by office_name
having sum(case when date between date '2015-01-01' and '2016-01-01' then 1 else 0 end) = 0;;

Comparing dates using SQL

I have a date that looks like this: 2014-10-01 12:35:29.440
the table looks like this:
ORDER 1 | 2014-07-31 00:00:00.000
ORDER 2 | 2015-07-31 00:00:00.000
sorry i wanted ORDER 2 to show up.. As my get date returns todays date and that is GREATER than 2014-07-31 00:00:00.000
Here is what i have tried:
SELECT TOP 1 NAME
FROM ORDER_DATES
WHERE GETDATE() > ORDER_DATE
ORDER BY NAME DESC
Your question still isn't quite worded in a way that is conducive to what you need... but I think I understand what you want now based on the comments.
Based on the comment:
IF it doesnt match the date then it needs to return the next row.
Which is ORDER 2
Something like this should work:
SELECT TOP 1 name
FROM ORDER_DATES o
INNER JOIN (
-- This subquery finds the first date that occurs *after* the current date
SELECT MIN(ORDER_DATE) AS ORDER_DATE
FROM ORDER_DATES
WHERE ORDER_DATE > GETDATE()
) minDateAfterToday ON o.ORDER_DATE = minDateAfterToday.ORDER_DATE
ORDER BY name
This would work a lot better if you had an ID field in the table, but this should work with the given data, you'll potentially run into issues if you have two orders on the exact same date.
EDIT:
here's a fiddle showing the query in action:
http://sqlfiddle.com/#!6/f3057/1
DATEDIFF will come handy, also you have to order by ORDER_DATE:
SELECT TOP 1 NAME
FROM ORDER_DATES
WHERE DATEDIFF(DAY,ORDER_DATE,GETDATE())>0
ORDER BY ORDER_DATE DESC
You can write as:
SELECT NAME
FROM ORDER_DATES
WHERE cast(GETDATE()as date) > cast (ORDER_DATE as date)
ORDER BY NAME DESC
Demo
Check if you are querying against right table
declare #dt datetime = cast('2014-10-01 12:35:29.440' as datetime), #dt2 datetime= cast('2014-07-31 00:00:00.000' as datetime);
print(case when #dt > #dt2 then 1 else 0 end);
This piece of script shows output 1 i.e. condition should match for ORDER 1.
Verify if you are missing some thing.
Edit as per change to original question:
here the condition needed be reverted as date value is in future which is greater than current date
new query will be as
SELECT TOP 1 NAME
FROM ORDER_DATES
WHERE ORDER_DATE > GETDATE()
ORDER BY NAME DESC

SQL -- return 0s if no group exists

I have a rollup table that sums up raw data for a given hour. It looks something like this:
stats_hours:
- obj_id : integer
- start_at : datetime
- count : integer
The obj_id points to a separate table, the start_at field contains a timestamp for the beginning of the hour of the data, and the count contains the sum of the data for that hour.
I would like to build a query that returns a set of data per day, so something like this:
Date | sum_count
2014-06-01 | 2000
2014-06-02 | 3000
2014-06-03 | 0
2014-06-04 | 5000
The query that I built does a grouping on the date column and sums up the count:
SELECT date(start_at) as date, sum(count) as sum_count
FROM stats_hours GROUP BY date;
This works fine unless I have no data for a given date, in which case it obviously leaves out the row:
Date | sum_count
2014-06-01 | 2000
2014-06-02 | 3000
2014-06-04 | 5000
Does anyone know of a good way in SQL to return a zeroed-out row in the case that there is no data for a given date group? Maybe some kind of case statement?
You need a full list of dates first, then connect that list to your available dates and group by that. Try the following:
--define start and end limits
Declare #todate datetime, #fromdate datetime
Select #fromdate='2009-03-01', #todate='2014-06-04'
;With DateSequence( Date ) as
(
Select #fromdate as Date
union all
Select dateadd(day, 1, Date)
from DateSequence
where Date < #todate
)
--select result
SELECT DateSequence.Date, SUM(Stats_Hours.Count) AS Sum_Count
FROM
DateSequence
LEFT JOIN
Stats_Hours ON DateSequence.Date = Stats_Hours.Start_At
GROUP BY DateSequence.Date
option (MaxRecursion 0)
EDIT: CTE code from this post

Get the nearest/lowest Date SQL

I have four dates with a different prices for each date:
10/01/2011 $25
10/08/2011 $50
11/17/2011 $100
12/23/2011 $150
SQL:
SELECT price FROM MyTable WHERE MyDate <= '10/12/2011'
PROBLEM: This query returns $25 and $50. I need it to give me the nearest date only...
How can i have it return only the $50?
SELECT top 1 price FROM MyTable WHERE MyDate <= '10/12/2011' order by MyDate desc
Try this (in SQL Server)
SELECT TOP 1 price
FROM MyTable
WHERE myDate <= getDate()
ORDER BY myDate DESC
Try this (in mySQL)
SELECT price
FROM MyTable
WHERE myDate <= now()
ORDER BY myDate DESC
LIMIT 1