Join operation on two tables retrieving dates - sql

My first query, retrieving date and hours worked from work_details of a given employee number in a given date.
SELECT date,
SEC_TO_TIME( SUM( TIME_TO_SEC( `total_hours` ) ) ) AS total
FROM `work_details`
WHERE employee_id='28'
and date between '2012-02-01'
and '2012-02-29'
GROUP BY DATE ORDER BY DATE
and the Second query retrieving date from table holy_date:
SELECT holy_date
from holiday
where holy_date between '2012-02-01' and '2012-02-29'
I need to combine results of the two queries in the correct date order.
I tried union operation,but dint get result.
How can I do it?

There are a few ways to achieve what you want.
This is not the documented way of doing it. But this should work.
SELECT date, total
FROM
(
SELECT date, SEC_TO_TIME( SUM( TIME_TO_SEC( `total_hours` ) ) ) AS total
FROM `work_details`
WHERE employee_id='28' AND date BETWEEN '2012-02-01' AND '2012-02-29'
GROUP BY date
UNION ALL
(
SELECT holy_date AS date, NULL AS total
FROM holiday
WHERE holy_date BETWEEN '2012-02-01' AND '2012-02-29'
)
) AS t
GROUP BY date
ORDER BY date

Related

How do I calculate how many X requests were open as of each date?

Using
https://data.seattle.gov/Public-Safety/PDRs-After-using-City-of-Seattle-Public-Records-Re/wj44-r6br/data I want the know on each date the number of public disclosure requests were open. This means per date I want the number of requests created before or same day as date and don't have a close date after the date.
I copied it to https://data.world/timacbackup/seattle-police-public-disclosure-requests where I can use SQL.
The closest I've gotten is
SELECT CAST(seattle_police_records_requests.request_create_date AS DATE) AS the_date,
count(*)
FROM seattle_police_records_requests
GROUP BY CAST(seattle_police_records_requests.request_create_date AS DATE)
ORDER BY the_date DESC;
I tried
SELECT CAST(request_create_date AS DATE) AS the_date,
count((
SELECT request_create_date
FROM seattle_police_records_requests AS t
WHERE CAST(t.request_create_date AS DATE) < d.request_create_date
))
FROM seattle_police_records_requests AS d
GROUP BY CAST(request_create_date AS DATE)
ORDER BY the_date DESC;
but get unknown table 'd' for the count subquery.
The last query I tried is
WITH dates
AS (
SELECT CAST(request_create_date AS DATE) AS create_date,
CAST(request_closed_date AS DATE) AS closed_date
FROM seattle_police_records_requests
),
create_dates
AS (
SELECT DISTINCT CAST(request_create_date AS DATE) AS create_date
FROM seattle_police_records_requests
)
SELECT create_dates.create_date,
COUNT(*)
FROM dates
INNER JOIN create_dates ON dates.create_date = create_dates.create_date
GROUP BY create_dates.create_date
HAVING dates.create_date <= create_dates.create_date
ORDER BY create_dates.create_date DESC
and basically it's just counting # of requested opened on given day not all that were open as of given day.
After importing the "created" and "closed" values into SQL Server as datetime columns I was able to generate the counts per day like so:
WITH
given_dates AS
(
SELECT DISTINCT CAST(created AS DATE) AS given_date
FROM seattle_police_records_requests
)
SELECT
given_date,
(
SELECT COUNT(*)
FROM seattle_police_records_requests
WHERE created <= DATEADD(DAY, 1, given_date) AND (closed > given_date OR closed IS NULL)
) AS num_open
FROM given_dates
ORDER BY given_date;
The DATEADD was necessary to include requests opened during that day, since the comparison of a date and a datetime implies that the date value is midnight (i.e., the very beginning of that day).

getting data for individual months using single query

Im having 3 tables as per below picture (im giving just sample data but actual tables having data for all months). My SALES table will contain the data both for future(which were sold in future) and past dates.
select item_id as agg from item_category f JOIN
sales t ON f.item_id=t.item_id where t.selling_date
BETWEEN sysdate AND sysdate+21 and f.item_type='medicine';
and now my query returns ITEMS which were sold for next 21 days. Now i want to get the profit of these ITEMS for past one year
For example i want the profit for last one year as Jan:2000,feb:3000,mar:1000.......
To get the output in rows:
SELECT -- s.item_id, -- Not sure if you want it total or per item
TRUNC( s.sold_date, 'MM' ) AS sold_month,
SUM( r.profit ) AS total_profit
FROM sales s
INNER JOIN
revenue_table r
ON ( s.item_id = r.item_id )
GROUP BY -- s.item_id, -- Not sure if you want it total or per item
TRUNC( s.sold_date, 'MM' )
To PIVOT the rows into columns:
SELECT *
FROM (
SELECT -- s.item_id, -- Not sure if you want it total or per item
TRUNC( s.sold_date, 'MM' ) AS sold_month,
r.profit
FROM sales s
INNER JOIN
revenue_table r
ON ( s.item_id = r.item_id )
)
PIVOT ( SUM( profit ) FOR sold_month IN (
DATE '2017-05-01' AS May2017,
DATE '2017-04-01' AS Apr2017,
DATE '2017-03-01' AS Mar2017,
DATE '2017-02-01' AS Feb2017,
DATE '2017-01-01' AS Jan2017,
DATE '2016-12-01' AS Dec2016,
DATE '2016-11-01' AS Nov2016,
DATE '2016-10-01' AS Oct2016
) )
You could group items by date of sale and aggregate this profit.
SELECT
YEAR(sold_date) AS `Year`,
MONTH(sold_date) AS `Month`,
SUM(profit) AS Profit
FROM sales JOIN Reventue_Table ON sales.item_id=Reventue_Table.item_id
GROUP BY `Year`, `Month`;
If you want to get result for specific year, use HAVING clause. For SQL use DATEPART() function. For oracle use EXTRACT().

How to group orders by Date

I have a order details table and I want to find the sum of price by each date and display them as
For Ex
count sum date
5 619.95 2015-11-19
3 334.97 2015-11-18
4 734.96 2015-11-18
5 1129.95 2015-11-18
I have written the query for getting the count and sum as
select count(id), sum([price])
from [OrderDetails]
where [date]between '2015-10-29 05:15:00' and '2015-11-09 00:01:00'
group by datepart(day,[date])
But not able to achieve with date. How can it be done?
You need to include what you are grouping on in the SELECT portion of your query:
select count(id), sum([price]), datepart(day,[date]) as [date]
from [OrderDetails]
where [date] between '2015-10-29 05:15:00' and '2015-11-09 00:01:00'
group by datepart(day,[date]);
It seems like your column called date has both a date and time component. I would suggest converting it to a date, for both the select and group by:
select count(id), sum(price), cast([date] as date) as thedate
from OrderDetails
where [date] between '2015-10-29 05:15:00' and '2015-11-09 00:01:00'
group by cast([date] as date)
order by thedate;
Note: date is a poor name for a column, because it is the name of a built-in type.

SQL Server return date range and associated value between specified values

I'm fetching records from the DB using a query like:
SELECT date as "Date", count(date) as "NumIssues"
FROM Issues
WHERE Date BETWEEN '2015-03-25' AND '2015-03-28'
GROUP BY date
ORDER BY date;
The query works fine but I need it to fetch results even if there are no values for the specified date and return 0 for the NumIssues value.
Would the best way to go about this would be to put in case statements? Thanks in advance!
;WITH dates ( "Date" ) AS (
SELECT CONVERT( DATE, '2015-03-25' )
UNION ALL
SELECT DATEADD( DAY, 1, Date )
FROM dates
WHERE DATEADD( DAY, 1, Date ) < '2015-03-28'
)
SELECT d.Date
, COUNT(date) as "NumIssues"
FROM dates AS d
LEFT JOIN Issues AS i
ON i.date = d.Date
GROUP BY d.date
ORDER BY d.date;

How do I get a maximium daily value of a numerical field over a year in SQL

How do I get a maximium daily value of a numerical field over a year in MS-SQL
This would query the daily maximum of value over 2008:
select
datepart(dayofyear,datecolumn)
, max(value)
from yourtable
where '2008-01-01' <= datecolumn and datecolumn < '2009-01-01'
group by datepart(dayofyear,datecolumn)
Or the daily maximum over each year:
select
datepart(year,datecolumn),
, datepart(dayofyear,datecolumn)
, max(value)
from yourtable
group by datepart(year,datecolumn), datepart(dayofyear,datecolumn)
Or the day(s) with the highest value in a year:
select
Year = datepart(year,datecolumn),
, DayOfYear = datepart(dayofyear,datecolumn)
, MaxValue = max(MaxValue)
from yourtable
inner join (
select
Year = datepart(year,datecolumn),
, MaxValue = max(value)
from yourtable
group by datepart(year,datecolumn)
) sub on
sub.Year = yourtable.datepart(year,datecolumn)
and sub.MaxValue = yourtable.value
group by
datepart(year,datecolumn),
datepart(dayofyear,datecolumn)
You didn't mention which RDBMS or SQL dialect you're using. The following will work with T-SQL (MS SQL Server). It may require some modifications for other dialects since date functions tend to change a lot between them.
SELECT
DATEPART(dy, my_date),
MAX(my_number)
FROM
My_Table
WHERE
my_date >= '2008-01-01' AND
my_date < '2009-01-01'
GROUP BY
DATEPART(dy, my_date)
The DAY function could be any function or combination of functions which gives you the days in the format that you're looking to get.
Also, if there are days with no rows at all then they will not be returned. If you need those days as well with a NULL or the highest value from the previous day then the query would need to be altered a bit.
Something like
SELECT dateadd(dd,0, datediff(dd,0,datetime)) as day, MAX(value)
FROM table GROUP BY dateadd(dd,0, datediff(dd,0,datetime)) WHERE
datetime < '2009-01-01' AND datetime > '2007-12-31'
Assuming datetime is your date column, dateadd(dd,0, datediff(dd,0,datetime)) will extract only the date part, and then you can group by that value to get a maximum daily value. There might be a prettier way to get only the date part though.
You can also use the between construct to avoid the less than and greater than.
Group on the date, use the max delegate to get the highest value for each date, sort on the value, and get the first record.
Example:
select top 1 theDate, max(theValue)
from TheTable
group by theDate
order by max(theValue) desc
(The date field needs to only contain a date for this grouping to work, i.e. the time component has to be zero.)
If you need to limit the query for a specific year, use a starting and ending date in a where claues:
select top 1 theDate, max(theValue)
from TheTable
where theDate between '2008-01-01' and '2008-12-13'
group by theDate
order by max(theValue) desc