Need help to make a query - sql

The query below returns two columns - dateOfBusiness, a datetime and salesOnDate, an int. This is the sales generated by one store with an area code storeId for each day. The result set consists of 500-600 rows.
I want to get the average sales for a month, ie do average of salesOnDate. I wanted to use sub query as shown in this SO question. But it did not work for me. How do i do this ?
select count(salesOnDate)
from dbo.localSales
where productName like '%juice%'
and storeId = 'MUN123'
group by dateOfBusiness
I tried to do it like this, but it does not work -
select sum(x.count)
from
(
select count(id) as 'count'
from table
) x
Additional info -
Table structure -
dateOfBusiness | salesOnDate
-------------------------------
2013-10-5 | 200
2013-10-6 | 100
2013-10-7 | 700
I want to sum salesOnDate for any period of time, say one month.

This will give you the average sales by month along with the total number of sales for that month:
-- can use DATEPART instead of DATENAME if you prefer numbered months (i.e., 1 = January, 2 = February, etc.)
SELECT DATENAME(month, dateOfBusiness) [Month], SUM(salesOnDate) [TotalSales], AVG(salesOnDate) [AverageSales]
FROM dbo.localSales
WHERE productName like '%juice%'
AND storeId = 'MUN123'
GROUP BY DATENAME(month, dateOfBusiness)
The important part of the query is the DATENAME (or DATEPART if you use that) function, which will only take specific information from your date column, rather than the entire value.
For example, lat's say you have three records for April 11, 2013
dateOfBusiness salesOnDate
--------------------- -----------
2013-04-11 08:03:24 5
2013-04-11 11:45:17 1
2013-04-11 20:23:52 3
Using the query above will show them grouped into one month:
Month TotalSales AverageSales
----------------- -------------- ----------------
April 9 3

Are you sure you don't want sum(salesOnDate) instead of count(salesOnDate)? Count returns the number of rows, sum will return the total of all the row values.
The Average function is AVG, so you could say:
select
dateOfBusiness,storeId ,
count(salesOnDate), sum(salesOnDate), avg(salesOnDate)
from
dbo.localSales
where
productName like '%juice%'
and storeId = 'MUN123'
group by
dateOfBusiness,storeId
OK, given the edits to your question, try:
select
storeId , dob_yr, dob_mo, count(salesOnDate), sum(salesOnDate), avg(salesOnDate)
from (
select
dateOfBusiness,storeId , year(dateOfBusiness) as dob_yr,
month(dateOfBusiness) as dob_mo,
salesOnDate
from
dbo.localSales
where
productName like '%juice%'
and storeId = 'MUN123'
) t
group by
storeId , dob_yr, dob_mo

Related

how to calculate the total value of orders on each day where we have the time in date (it doesn't do the SUM function)? SQL ORACLE

I am struggling with the time in order_date column. I deleted the time from date format (order_date) but THE SUM doesn't calculate the result. Let's say that we have 3 orders (20$, 15$,10$) in 1st Jul 2022 and it doesn't show the result 45$. It shows 3 line for 1st July 2022.I suspected that time influenced the solution which I would like to achieve.
PS I set the data for discount number is 1 - function WHERE
SELECT
TO_CHAR(ORDER_DATE, 'DD/MM/YYYY'),
SUM(order_total) as total
FROM
oe.orders
WHERE promotion_id = 1
GROUP BY order_date;
I cut the time in date column (order_date) and I can't move on.
2ND QUESTION
If I would like to add the second discount (WHERE promotion_id = 1 or promotion_id = 2) and after I need to sum up the amount for separate discounts (promotion_id = 1 & 2). How could I calculate this?
Could you use the trunc function to remove the time part of the order_date column before grouping the records by date?
Like:
SELECT
TRUNC(order_date) AS order_date,
SUM(order_total) as total
FROM
oe.orders
WHERE promotion_id = 1
GROUP BY TRUNC(order_date);

Microsoft Access - Calling upon a separate table to define a date range in a query

I am new to Access and am trying to learn as I go.
I have a table that tracks the amount of consumables used that day and there could be multiple entries for one day. For example, it looks like
Date | Consumable x | Consumable y
'8/24/2017'| '4' | '3'
'8/24/2017'| '6' | '1'
I have a second table that defines my weeks. For example, it looks like
WeekID | WeekCounter | WeekStartDate | WeekEndDate
'1' | 'Week 1' | '1/4/2017' | '1/10/2017'
I want to make a query that can sum all of the consumables for each week, based on the range defined in the week table. The end product should look like:
Week | Consumable x | Consumable y
'Week 20'| '24' | '44'
'Week 21'| '30' | '41'
I have tried a number of different approaches but am not confident with anything I have tried. Any help would be greatly appreciated!
Thank you
You can do like this:
Select
WeekCounter As Week,
Sum([Consumable x]) As TotalX,
Sum([Consumable y]) As TotalY
From
TableConsume,
TableWeek
Where
TableConsume.Date Between WeekStartDate And WeekEndDate
Group By
WeekCounter
You need to use a subquery. Something along these lines:
SELECT SUM([Consumable x]) AS SumX, SUM([Consumable Y]) AS SumY, Week FROM
(SELECT Table1.[Consumable x], Table1.[Consumable y], Table2.[Week] FROM
table1 inner join table2 on table1.mydate >= table2.WeekStartDate and table1.mydate <= table2.WeekEndDate)
GROUP BY Week
I note you have week 1 as 4th Jan to 10th Jan, so I presume you actually have the WeekEndDate as 23:59:59 (ie 1 second to midnight). The alternative is to have your week table with dates 7 days apart, and then change the <= table2.WeekEndDate to simply < table2.WeekEndDate.
You could use this method. Like #Jonathan I've used dDate rather than Date for the same reasons (reserved words).
This can only be viewed in SQL and not Design view as Access can't represent the join.
SELECT WeekCounter
, NZ(SUM(Consumable_X),0) AS C_X
, NZ(SUM(Consumable_Y),0) AS C_Y
FROM WeekDefinition LEFT JOIN Consumables ON WeekDefinition.WeekStartDate<=Consumables.dDate AND
WeekDefinition.WeekEndDate>=Consumables.dDate
GROUP BY WeekCounter, WeekID
ORDER BY WeekID
I'd have to question your reasoning behind the Consumables table though:
At the moment you've got Consumable X and Consumable Y in different fields. What happens over the years as you add Coonsumables A, B, C & Z? Each time you'll have to update your table and each query to count the new consumable.
Wouldn't it be better to change the table to hold three fields: Date, Consumable_Type and Consumable_Amount (you may want to add another field to create a primary key).
Your records would hold values such as:
'8/24/17' | 'Consumable X' | '4' and '8/24/17' | 'Consumable Y' | '3'
Your query would then look like this:
SELECT WeekCounter
, Consumable_Type
, SUM(Consumable_Amount) AS Total
FROM WeekDefinition LEFT JOIN Consumables ON WeekDefinition.WeekEndDate>=[Consumables].dDate AND
WeekDefinition.WeekStartDate<=[Consumables].dDate
GROUP BY WeekCounter, WeekID, Consumable_Type
ORDER BY WeekID
A cross-tab query would return the table as you want:
TRANSFORM Sum(Total) AS SumOfTotal
SELECT WeekCounter
FROM MyQuery
GROUP BY WeekCounter
PIVOT Consumable_Type
I tried to combine the above two queries into one, but couldn't quite get there:
TRANSFORM SUM(Total) AS Total_Consumables
SELECT WeekCounter, Consumable_Type, Total
FROM
(
SELECT WeekCounter
, Consumable_Type
, SUM(Consumable_Amount) AS Total
FROM WeekDefinition LEFT JOIN Consumables ON WeekDefinition.WeekStartDate<=Consumables.dDate AND
WeekDefinition.WeekEndDate>=Consumables.dDate
GROUP BY WeekCounter, WeekID, Consumable_Type
ORDER BY WeekID
) AS Q1
GROUP BY WeekCounter, Consumable_Type, Total
PIVOT Consumable_Type

How to link a database table to itself and get the query results

I need your help in getting the data from a table called "Earnings" and to link it to itself twice. The "Earnings" table has the columns:
PaymentDate EmployeeID Description Amount
30-Jun-2016 111 Basic 100
30-Jun-2016 111 Telephone 20
31-May-2016 111 Basic 100
31-May-2016 111 Telephone 10
31-May-2016 222 Basic 200
I got a requirement to prepare a query to calculate the differences of the employees payments between the selected month "Jun-2016" and the previous month and I should add 3 more columns (Current Month Payment - Last Month Payment - Difference).
If the payments are the same with the previous month, I shouldn't show them. But, if the payment is exist in the previous month and it is not available in this month or null for this month, I should show its value for the previous month and for the current month I should show it as zero.
I only started to initiate the query and then I need your help to continue:
select e.paymentdate, e.employeeid,e.Description,e.amount
from earnings e, earnings x
where e.employeeid = x.employeeid
3 fields need to be added currentmonthpayment - previousmonthpayment - difference (current-previous)
You can use the below SQL to get the desired data
select e.employeeid, current_month_earning, prev_month_earning, (current_month_earning - prev_month_earning ) as difference
from
(
select
employeeid
, sum(amount) as current_month_earning
from
earnings
where
to_char(paymentdate,'YYYYMM') = to_char(SYSDATE,'YYYYMM')
group by
employeeid
) current_month_earnings
(
select
employeeid
, sum(amount) as prev_month_earning
from
earnings
where
to_char(paymentdate,'YYYYMM') = to_char(trunc(SYSDATE,'MM')-1,'YYYYMM')
group by
employeeid
) prev_month_earnings
where current_month_earnings.employeeid = prev_month_earnings.employeeid

SQL - Counting months passed by a Person Indicator

I'm trying to count the number of months that have passed based on ID, it's possible that for some records the months will not increase by 1 each time (i.e. someone could have a record for 1/1/13 and 3/1/13 but not 2/1/13) however I only want a count of the records in my table. So missing months don't matter.
An example table would be: (notice the missing month and it's irrelevancy).
DATE ID Months Passed
----------- --- --------------
2013-11-01 105 1
2013-12-01 105 2
2014-02-01 105 3
2014-03-01 105 4
Essentially an Excel COUNTIFSin SQL, which I've written:
=COUNTIFS(IDColumn, ID, MonthColumn, "<=" & Month)
Does anyone know of a way to generate the desired column using SQL?
Try ROW_NUMBER(). If you just want the "Months Passed" column to increase by 1 each time, and for each ID, that will do the trick.
SELECT
Date,
Id,
Indicator,
ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Date) AS RowNum
FROM YourTable
WHERE Indicator = 'YES'
UNION
SELECT
Date,
Id,
Indicator,
0 AS RowNum
FROM YourTable
WHERE Indicator = 'NO'
You could more simply count rows grouped by month (more complex if you have count months in different years separately):
SELECT COUNT(derived.monthVal)
FROM (SELECT MONTH(<your date field>) AS monthVal
FROM [your table]
WHERE [Your ID Column] = <the id>
GROUP BY MONTH(<your date field>)) AS derived;

Get name of person having activity in every month - Oracle SQL

I have log table where there is are records with user id and the date for a specific activity done. I want to get names of users having activity every month. I am using the following query
select distinct(employeeid) from transactions
where eventdate between '01-OCT-13' AND '23-OCT-13'
and eventdate between '01-SEP-13' AND '01-OCT-13'
and eventdate between '01-AUG-13' AND '01-SEP-13'
and eventdate between '01-JUL-13' AND '01-AUG-13';
But this is doesn't work. Can someone please suggest any improvement?
Edit:
Since my questions seems to be a little confusing, here is an example
EmployeeID | Timestamp
a | 01-Jul-13
b | 01-Jul-13
a | 01-Aug-13
c | 01-Aug-13
a | 01-Sep-13
d | 01-Sep-13
a | 01-Oct-13
a | 01-Oct-13
In the above table, we can see that employee "a" has activity in all the months from July till October. So I want to find a list of all such employees.
You can use COUNT as analytical function and get the number of months for each employee and total number of months. Then select only those employees where both counts match.
select distinct employeeid
from (
select employeeid,
count(distinct trunc(eventdate,'month')) --count of months for each employee
over (partition by employeeid) as emp_months,
count(distinct trunc(eventdate,'month')) --count of all months
over () as all_months,
from transactions
)
where emp_months = all_months;
Wish I could give you the code, but i'm in a bit of a hurry, so this is more of a suggestion.
Have you tried extracting the distinct months (from eventdate), for every user, and if that has 10 rows (assuming it is October, you could dynamically change this), then the employee must of had an event every month.
By very inefficient, I think you mean it doesn't work. The same value can't be both in september, in october, etc.
Anyway, using #LaggKing suggestion, you could try this query:
SELECT employeeid
FROM (
SELECT DISTINCT employeeid, MONTH(eventdate)
FROM transactions
)
HAVING COUNT(*) = MONTH(NOW())
EDIT: You need to take year into account.
SELECT employeeid
FROM (
SELECT DISTINCT employeeid, MONTH(eventdate)
FROM transactions
WHERE YEAR(eventdate) = YEAR(NOW())
)
HAVING COUNT(*) = MONTH(NOW())