Creating a TSQL query to make a report - sql

I am in the process of creating a report from the data I have stored in my database; just a little stuck on the next piece of it.
Here is an SQLFiddle of my structure
The report is run every Friday. It gets all records from the table that are within the last 7 days (since it was last reported).
The piece I need to add to my query is only get me records where the SUM of awardValue exceeds $75 in the current year.
I have it pulling my records for the time frame (since last report) but need to include that other piece.
How can I accomplish this?

Assuming that you don't care about the Award status when you calculate sum -
Select Main.*
from main
INNER JOIN(
SELECt EMPLOYEE,SUM(AWARDVALUE) SUM
FROM MAIN
WHERE YEAR(AWARDDATE) = YEAR(GetDate())
GROUP BY EMPLOYEE
HAVING SUM(AWARDVALUE)>75) EMPLIMIT
ON Main.EMPLOYEE = EMPLIMIT.EMPLOYEE
Where awardStatus = '1' AND awardDate BETWEEN GetDate() - 7 AND GetDate()
Modified query to Pull in SUM with results and TaxIt Column
Select Main.*,EmployeeSum,
CASE WHEN EmployeeSum>75 THEN 'Yes' ELSE 'No' END AS TaxIt
from main
INNER JOIN(
SELECt EMPLOYEE,SUM(AWARDVALUE) EmployeeSum
FROM MAIN
WHERE YEAR(AWARDDATE) = YEAR(GetDate())
GROUP BY EMPLOYEE) EMPLIMIT
ON Main.EMPLOYEE = EMPLIMIT.EMPLOYEE
Where awardStatus = '1' AND awardDate BETWEEN GetDate() - 7 AND GetDate()

for this you need to put after the group query the next.
SELECT A,B,C, SUM(D)
FROM TABLE
GROUP BY A,B,C
HAVING sum(awardValue) > 75

Related

Running Total - Create row for months that don't have any sales in the region (1 row for each region in each month)

I am working on the below query that I will use inside Tableau to create a line chart that will be color-coded by year and will use the region as a filter for the user. The query works, but I found there are months in regions that don't have any sales. These sections break up the line chart and I am not able to fill in the missing spaces (I am using a non-date dimension on the X-Axis - Number of months until the end of its fiscal year).
I am looking for some help to alter my query to create a row for every month and every region in my dataset so that my running total will have a value to display in the line chart. if there are no values in my table, then = 0 and update the running total for the region.
I have a dimDate table and also a Regions table I can use in the query.
My Query now, (Results sorted in Excel to view easier) Results Table Now
What I want to do; New rows highlighted in Yellow What I want to do
My Code using SQL Server:
SELECT b.gy,
b.sales_month,
b.region,
b.gs_year_total,
b.months_away,
Sum(b.gs_year_total)
OVER (
partition BY b.gy, b.region
ORDER BY b.months_away DESC) RT_by_Region_GY
FROM (SELECT a.gy,
a.region,
a.sales_month,
Sum(a.gy_total) Gs_Year_Total,
a.months_away
FROM (SELECT g.val_id,
g.[gs year] AS GY
,
g.sales_month
AS
Sales_Month,
g.gy_total,
Datediff(month, g.sales_month, dt.lastdayofyear) AS
months_away,
g.value_type,
val.region
FROM uv_sales g
JOIN dbo.dimdate AS dt
ON g.[gs year] = dt.gsyear
JOIN dimvalsummary val
ON g.val_id = val.val_id
WHERE g.[gs year] IN ( 2017, 2018, 2019, 2020, 2021 )
GROUP BY g.valuation_id,
g.[gs year],
val.region,
g.sales_month,
dt.lastdayofyear,
g.gy_total,
g.value_type) a
WHERE a.months_away >= 0
AND sales_month < Dateadd(month, -1, Getdate())
GROUP BY a.gy,
a.region,
a.sales_month,
a.months_away) b
It's tough to envision the best method to solve without data and the meaning of all those fields. Here's a rough sketch of how one might attempt to solve it. This is not complete or tested, sorry, but I'm not sure the meaning of all those fields and don't have data to test.
Create a table called all_months and insert all the months from oldest to whatever date in the future you need.
01/01/2017
02/01/2017
...
12/01/2049
May need one query per region and union them together. Select the year & month from that all_months table, and left join to your other table on month. Coalesce your dollar values.
select 'East' as region,
extract(year from m.month) as gy_year,
m.month as sales_month,
coalesce(g.gy_total, 0) as gy_total,
datediff(month, m.month, dt.lastdayofyear) as months_away
from all_months m
left join uv_sales g on g.sales_month = m.month
--and so on

Running total with Over

I'm trying to create a running total of the number of files per opened by day so I can use the data for a graph showing cumulative results.
The data is basically the file opening date, a calculated field showing 'This month' or 'Last Month' depending on the date and the running total field that I'm trying to figure out.
Date Month Count
==== ===== =====
2019-08-01 Last Month 6
2019-08-02 Last Month 2
2019-08-03 Last Month 5
I want to have a running total...so 6, 8, 13 etc
But all I'm getting is a row count (1,2,3 etc) for my count field.
select
FileDate,
Month,
sum(Count) OVER(PARTITION BY month order by Filedate) as 'Count'
from (
select
1 as 'Count',
Case
When month(cast(concat(right(d.var_val,4),substring(d.var_val,4,2),left(d.var_val,2)) as DATE) ) = Month(getdate()) then 'This Month'
else 'Last Month'
end as 'Month'
FROM data d
left join otherdata m on d.VAR_FileID = m.MAT_FileID
left join otherdata u on m.MAT_Fee_Earner = u.User_ID
left join otherdata br on m.MAT_BranchID = br.BR_ID
WHERE d.var_no IN ( '1628' )
and Len(var_val) = 10
)files
where Month(FileDate) in (MONTH(FileDate()),MONTH(getDate())-1)
and Year(Filedate) = Year(Getdate())
and Dept = 'Peterborough Property'
group by Month, FileDate, count
GO
I'm assuming I've not quite grasped the proper usage of 'OVER' - any pointers would be great!
The Partition clause indicates when to reset the count, so by partitioning by month you are only counting records for each discreet month to get a running total, over the whole dataset, you don't want the partition clause at all, just the order by clause.
Hope your clear with OVER clause now (with "Sentinel" answer), in which case you should replace desired column as follows, so that count continuously increase for all the rows from sub-query based on order by clause: for more details on OVER Clause..
sum(Count) OVER (Oder by Filedate) as [Count]
-- or
sum(Count) OVER (Oder by Filedate desc) as [Count]

Adding all values for certain dates and the following day

I am trying to do some reporting to see if an event drove sales on the day after the event as well. So for this I am trying to add all the sales from the day of an event and the day after it for each set of data. It does not matter which store the sale happened for the purpose of this report. However it is possible to have a day appear up to 22 times (1 for each store). All the data is stored in one table called UCS.
I have tried finding a way to make Lag or Lead work using case statements and temp tables but so far no luck.
Below are a couple of screenshots to help show what I am trying to do. I need to add the sales marked yellow for each screenshot.
You will notice in example 2 I am not adding the values from the days 11/4 or 11/13. While those are the next date in the data set they are not the next day on the calendar.
Example1
Example 2
Moments after posting this my brain clicked and figured it out. I can make a temp table pulling in a list of dates where there is an event doing a union to a list of dates equal to the dates of event +1 using a date table that just houses the dates of the calendar. Then use this to join back and limit the original table. Sample code below to better explain.
If OBJECT_ID('tempdb.dbo.#Event') IS NOT NULL DROP TABLE #Event
Select *
Into #Event
From (
Select
Universal_ID
,Date
From UCS
Where Month = 11
and Year = 2018
and Event = 1
Union
Select
Universal_ID
,DL.Date
From UCS
Join DateLookup as DL
on DATEADD(d,1,UCS.Date) = DL.Date
Where UCS.Month = 11
and UCS.Year = 2018
and Event = 1
) as A
Select
Sum(Sale) as Sale
From UCS
Join #Event as E
on UCS.Universal_ID = E.Universal_ID
and UCS.date = E.date
Where Month = 11
and Year = 2018
You don't really need a universal set of dates for this, if the date isn't in the UCS table it will not matter to the end result
select
sum(sale)
from UCS t
inner join (
select date from UCS where event = 1
union
select dateadd(day,1,date) from UCS where event = 1
) d on t.date = d.date
You can avoid a union in the subquery which may help avoid a pass through the UCS table by using a cross join, but this might not be worthwhile - only assessing execution plans would reveal this:
select
sum(sale)
from UCS t
inner join (
select distinct dateadd(day,cj.n,date) as date
from UCS
cross join (select 0 as n union all select 1) cj
where event = 1
) d on t.date = d.date
;

On SQL what would be the best way to do formulas?

I have the following structure
Columns structure
The date columns contain hours as well. I need to calculate the time beetween start and date on the same case number.
Example if case 1 has 2 subcases I need to calculate from the start date of the first one until the end date of the second one and add that to another column as "actual fixed time".
The thing is there could be 2 or 10 or 20 or more subcases.
Any thoughts?
You will want to use DATEDIFF in conjunction with GROUP BY
SELECT DATEDIFF(hour, MIN(start_date), MAX(end_date)) as ActualFixedTime FROM YourTable GROUP BY Casenumber
This will give you your actual fixed time for each case. In order to display this result for each row of your subcases, you join on it when selected your table:
SELECT YourTable.*, FixedTimes.ActualFixedTime
FROM YourTable
INNER JOIN (SELECT Casenumber,
DATEDIFF(hour, MIN(start_date), MAX(end_date)) AS ActualFixedTime
FROM YourTable
GROUP BY Casenumber)
AS FixedTimes
ON YourTable.Casenumber = FixedTimes.Casenumber

SQL multiple joins and sums on same table

I'm learning SQL on the fly as I work on a project and would appreciate some help with the following. I'm also fairly new to stackoverflow so I apologize if my formatting is off:
I have a table with columns Date, Group, Person, Amount. For every day I have an entry for each person with an amount and the group they're in, so one row would look like:
Date Group Person Amount
8/7/2012 A Steve 10
I'm trying to write a statement that will return the sum of all groups for two different days.
I have:
Select t1.group,sum(t1.amount),sum(t2.amount)
From table t1, table t2
Where t1.group=t2.group AND t1.date=current_date-1 AND t2.date=current_date-2
Group by t1.group
I'm not getting any errors but the two sums are different from what I get if I just do
Select date,sum(amount) From table Group by date
and look at the days in question.
Why are you joining between two tables?
I think you want:
Select t.group,
sum(case when t.date = current_date - 1 then t.amount end),
sum(case when t.date = current_date - 2 then t.amount end)
From table t
Group by t.group