UPDATE SQL Query to update a table based on two dates - database

i would like to update my query table based on two dates, i tried the following code but it didn't work
UPDATE [Stock Report] INNER JOIN Report ON [Stock Report].ItemID = Report.ItemID SET [Stock Report].Amount = SUM(Report.Amount) WHERE [Date Product Was Made] BETWEEN #AA AND #BB
My two query tables are Report and Stock Report
Report Table
ItemID| Item |Date Product Was Made|Amount|ProductID|Product Name
10 Flour 11/17/2015 100 54 Saltbread
11 Bran Flakes 11/17/2015 100 54 Saltbread
10 Flour 11/17/2015 100 54 Saltbread
11 Bran Flakes 11/17/2015 100 54 Saltbread
What i would like to see in Stock Report Table
ItemID| Item | Start Date | End Date |Amount
10 Flour 11/16/2015 11/25/2015 200
11 Bran Flakes 11/16/2015 11/25/2015 200
The dates can be any two random dates but the table should generate a total based on the amount used in between the date ranges. Wht]at would be the SQL code to complete this process

As EuphoriaGrogi mentioned, you were pretty close.
SELECT ItemID, Item, #AA AS StartDate, #BB AS EndDate, SUM(Amount) AS TotalAmount
FROM (YourReportTableQueryWith#AAAnd#BBParametersHere) AS SubQuery
GROUP BY SubQuery.ItemID,SubQuery.Item
More on GROUP BY here: http://www.w3schools.com/sql/sql_groupby.asp

You tagged with mysql, sql-server and ms-access.
But answers will differ for each case.
Here SQLServer solution:
WITH SumAmount AS (
SELECT
ItemId
,SUM(Report.amount) as sum_amount
FROM
Report
GROUP BY
ItemId
)
UPDATE SR
SET
amount = SA.sum_amount
FROM
[Stock Report] SR
JOIN SumAmount SA ON SR.ItemID = SA.ItemID
WHERE
[Date Product Was Made] BETWEEN #AA AND #BB
Supposed MS Access query (I'm not proficient with MSACCESS, going by http://www.fmsinc.com/microsoftaccess/query/snytax/update-query.html):
UPDATE [Stock Report]
JOIN (
SELECT
ItemId
,SUM(Report.amount) as sum_amount
FROM
Report
GROUP BY
ItemId
) SA ON [Stock Report].ItemID = SA.ItemID
SET
[Stock Report].amount = SA.sum_amount
WHERE
[Date Product Was Made] BETWEEN #AA AND #BB

Related

Table with 1-30 match data from database

I've been creating this table manually and hoping I can automate it.
What i have in excel is a table with with days of the Month example June 1-30 what I need to do is populate the data based on sales and a separate based on accumulative ... example
Data
1 - $100
2 - $300
5 - $300
What i need to see is :
1 - $100
2 - $400
3 - $400
4 - $400
5 - $700
What my issue is the days that have 0 / no sales does not populate into the database
here is the code I have to get the data :
IF DAY (GETDATE()) = 1
SELECT Office,NetNet_Revenue_USD,NetNet_GM_USD,[DayOfMonth],[Month],[Year]
FROM Datawarehouse.dbo.Sales_History Sales_History
WHERE (Sales_History.Cust_Intercompany <> 'Yes - VAP') AND Year = (YEAR(GETDATE())) and [Period] = MONTH(GETDATE()-1)
else IF DAY (GETDATE()) <> 1
SELECT Office,NetNet_Revenue_USD,NetNet_GM_USD,[DayOfMonth],[Month],[Year]
FROM Datawarehouse.dbo.Sales_History Sales_History
WHERE (Sales_History.Cust_Intercompany <> 'Yes - VAP') AND Year = (YEAR(GETDATE())) and [Period] = MONTH(GETDATE())
Any help would be apricated as I'm over doing it manually :(
New code using the idea of joining my data to a table that has every day of the month
SELECT distinct CONVERT(DATETIME, CAST(AUDTDATE AS VARCHAR(8)), 112) as StringToDate
,Office,(NetNet_Revenue_USD),[DayOfMonth],[Month],[Year],InvoiceNumber,Revenue_Func
FROM [ACCPACAU].[dbo].[CSCRD]
left join Datawarehouse.dbo.Sales_History on Sales_History.TranDate = CONVERT(DATETIME, CAST(AUDTDATE AS VARCHAR(8)), 112)
where year(CONVERT(DATETIME, CAST(AUDTDATE AS VARCHAR(8)), 112)) = (YEAR(GETDATE()))
and
Month(CONVERT(DATETIME, CAST(AUDTDATE AS VARCHAR(8)), 112)) = MONTH(GETDATE())
One way to do this is to run a union statement to get all the office location you want, aggregate the data and then do a sum over to get a running total. I have come up with a simplified version of the same.. hope this helps you achieve what you want.
I've kept it pretty simple to show what you could do
if object_id('tempdb..#office') is not null
drop table #office
if object_id('tempdb..#data') is not null
drop table #data
;with offices as (
select 1 as office
union all
select 2 as office
union all
select 3 as office
union all
select 4 as office
union all
select 5 as office
)
Select * into #office
from offices
;with sales as (
select 1 as office , 100 as sales
union all
select 2 as office , 300 as sales
union all
select 5 as office , 300 as sales
)
Select * into #data
from sales
; with all_data as (
select #data.*
from #data
union
select office,0 as sales
from #office
where office NOT IN (select office from #data)
)
Select
office
, sales
, sum(sales) over ( order by office) as runing_total
from all_data
drop table #data
drop table #office

create date range report based on history table

We have been keeping track of some changes in a History Table like this:
ChangeID EmployeeID PropertyName OldValue NewValue ModifiedDate
100 10 EmploymentStart Not Set 1 2013-01-01
101 10 SalaryValue Not Set 55000 2013-01-01
102 10 SalaryValue 55000 61500 2013-03-20
103 10 SalaryEffectiveDate 2013-01-01 2013-04-01 2013-03-20
104 11 EmploymentStart Not Set 1 2013-01-21
105 11 SalaryValue Not Set 43000 2013-01-21
106 10 SalaryValue 61500 72500 2013-09-20
107 10 SalaryEffectiveDate 2013-04-01 2013-10-01 2013-09-20
Basically if an Employee's Salary changes, we log two rows in the history table. One row for the Salary value itself and the other row for the salary effective date. So these two have identical Modification Date/Time and are kind safe to assume that are always after each other in the database. We can also assume that Salary Value is always logged first (so it is one record before the corresponding effective date
Now we are looking into creating reports based on a given date range into a table like this:
Annual Salary Change Report (2013)
EmployeeID Date1 Date2 Salary
10 2013-01-01 2013-04-01 55000
10 2013-04-01 2013-10-01 61500
10 2013-10-01 2013-12-31 72500
11 2013-03-21 2013-12-31 43000
I have done something similar in the past by joining the table to itself but in those cases the effective date and the new value where in the same row. Now I have to create each row of the output table by looking into a few rows of the existing history table. Is there an straightforward way of doing this whitout using cursors?
Edit #1:
Im reading on this and apparently its doable using PIVOTs
Thank you very much in advance.
You can use self join to get the result you want. The trick is to create a cte and add two rows for each EmployeeID as follows (I call the history table ht):
with cte1 as
(
select EmployeeID, PropertyName, OldValue, NewValue, ModifiedDate
from ht
union all
select t1.EmployeeID,
(case when t1.PropertyName = "EmploymentStart" then "SalaryEffectiveDate" else t1.PropertyName end),
(case when t1.PropertyName = "EmploymentStart" then t1.ModifiedDate else t1.NewValue end),
(case when t1.PropertyName = "SalaryValue" then t1.NewValue
when t1.PropertyName = "SalaryEffectiveDate" then "2013-12-31"
when t1.PropertyName = "EmploymentStart" then "2013-12-31" end),
"2013-12-31"
from ht t1
where t1.ModifiedDate = (select max(t2.ModifiedDate) from ht t2 where t1.EmployeeID = t2.EmployeeID)
)
select t3.EmployeeID, t4.OldValue Date1, t4.NewValue Date2, t3.OldValue Salary
from cte1 t3
inner join cte1 t4 on t3.EmployeeID = t4.EmployeeID
and t3.ModifiedDate = t4.ModifiedDate
where t3.PropertyName = "SalaryValue"
and t4.PropertyName = "SalaryEffectiveDate"
order by t3.EmployeeID, Date1
I hope this helps.
It is a little over kill to use pivot since you only need two properties. Use GROUP BY can also achieve this:
;WITH cte_salary_history(EmployeeID,SalaryEffectiveDate,SalaryValue)
AS
(
SELECT EmployeeID,
MAX(CASE WHEN PropertyName='SalaryEffectiveDate' THEN NewValue ELSE NULL END) AS SalaryEffectiveDate,
MAX(CASE WHEN PropertyName='SalaryValue' THEN NewValue ELSE NULL END) AS SalaryValue
FROM yourtable
GROUP BY EmployeeID,ModifiedDate
)
SELECT EmployeeID,SalaryEffectiveDate,
LEAD(SalaryEffectiveDate,1,'9999-12-31') OVER(PARTITION BY EmployeeID ORDER BY SalaryEffectiveDate) AS SalaryEndDate,
SalaryValue
FROM cte_salary_history

T-SQL Query to remove duplicate records in the output based on one particular column

I am running SQL Server 2014 and I have the following T-SQL query:
USE MYDATABASE
SELECT *
FROM RESERVATIONLIST
WHERE [MTH] IN ('JANUARY 2015','FEBRUARY 2015')
RESERVATIONLIST mentioned in the code above is a view. The query gives me the following output (extract):
ID NAME DOA DOD Nights Spent MTH
--------------------------------------------------------------------
251 AH 2015-01-12 2015-01-15 3 JANUARY 2015
258 JV 2015-01-28 2015-02-03 4 JANUARY 2015
258 JV 2015-01-28 2015-02-03 2 FEBRUARY 2015
The above output consist of around 12,000 records.
I need to modify my query so that it eliminates all duplicate ID and give me the following results:
ID NAME DOA DOD Nights Spent MTH
--------------------------------------------------------------------
251 AH 2015-01-12 2015-01-15 3 JANUARY 2015
258 JV 2015-01-28 2015-02-03 4 JANUARY 2015
I tried something like this, but it's not working:
USE MYDATABASE
SELECT *
FROM RESERVATIONLIST
WHERE [MTH] IN ('JANUARY 2015', 'FEBRUARY 2015')
GROUP BY [ID]
HAVING COUNT ([MTH]) > 1
Following query will return one row per ID :
SELECT * FROM
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT NULL)) rn FROM RESERVATIONLIST
WHERE [MTH] IN ('JANUARY 2015','FEBRUARY 2015')
) T
WHERE rn = 1
Note : this will return a random row from multiple rows having same ID. IF you want to select some specific row then you have to define it in order by. For e.g. :
SELECT * FROM
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DOA DESC) rn FROM RESERVATIONLIST
WHERE [MTH] IN ('JANUARY 2015','FEBRUARY 2015')
) T
WHERE rn = 1
definitely, it will return the row having max(DOA).
You are trying to do a GROUP BY statement which IMHO is the right way to go. You should formulate all columns that are a constant, and roll-up the others. Depending on the value of DOD and DOA I can see two solutions:
SELECT ID,NAME,DOA,DOD,SUM([Nights Spent]) as Nights,
min(MTH) as firstRes, max(MTH) as lastRes
FROM RESERVATIONLIST
GROUP BY ID,NAME,DOA,DOD
OR
SELECT ID,NAME,min(DOA) as firstDOA,max(DOD) as lastDOD,SUM([Nights Spent]) as Nights,
min(MTH) as firstRes, max(MTH) as lastRes
FROM RESERVATIONLIST
GROUP BY ID,NAME

use query results for another query sql

I know that there are many topics discussing nested queries, however I am getting errors on my nested query due to the functions I am using.
Sample Data:
Sample TestDate Column:
2015-05-13 13:45:14.000
2015-05-15 07:33:13.000
2015-05-18 06:07:11.000
2015-05-19 02:58:13.000
2015-05-22 14:08:42.000
2015-05-26 11:01:29.000
2015-05-26 11:01:50.000
2015-05-27 07:19:32.000
2015-05-15 08:04:28.000
2015-05-15 10:32:23.000
2015-05-22 14:11:26.000
2015-05-27 07:16:57.000
2015-05-29 08:50:36.000
2015-05-15 10:38:23.000
2015-05-19 03:08:53.000
2015-05-27 13:41:47.000
2015-05-29 08:47:56.000
2015-05-15 07:50:04.000
2015-05-18 06:20:28.000
2015-05-19 06:32:24.000
2015-05-26 11:00:58.000
2015-05-22 14:12:15.000
2015-05-26 10:57:17.000
I am looking to query the last 7 DATES with data (may not be the last 7 days).
My query to return the last 7 Dates with data works well.
-- Set the return record count to the last 7 days
SET ROWCOUNT 7
--Get the Distinct Dates
SELECT DISTINCT(CONVERT(VARCHAR, CONVERT(DATETIME,[TestDate]),23)) AS DT
FROM [SERVER].[dbo].[TABLE]
--Get the last 60 days
WHERE [TestDate] BETWEEN (Getdate() - 60) AND Getdate()
--Start at the current date and go backwards.
ORDER BY DT DESC
-- reset the return record count to prevent issues with further queries.
SET ROWCOUNT 0
This provides the following result:
DT
2015-05-29
2015-05-27
2015-05-26
2015-05-22
2015-05-19
2015-05-18
2015-05-15
Now, I want to use those 7 entries to pull the data for those dates.
Usually I would do a
SELECT * WHERE [TestDate] >= '2015-05-29' AND [TestDate] <= '2015-05-30'
for example (cumbersome I know).
A) I get errors with the SET function in a nested query.
B) How to make the proper WHERE statement. One option is to use the first and last result (2015-05-29 and 2015-05-15) from the query
(WHERE [TestDate] >= 'FIRST_RESULT' AND [TestDate] <= 'LAST_RESULT')
EDIT:
So from the table I added above, I would want data from 2015-05-15 - 2015-05-29 (ie the results from the query), but not from the data on date 2015-05-13, since data from the 13 th is the 8 th day.
This would give you the last 7 dates with data without having to do what you've done in your sample code:
SELECT DISTINCT TOP 7
CAST([TestDate] AS DATE) DT
FROM YourTable
ORDER BY CAST([TestDate] AS DATE) DESC
I've cast them to DATE to get the date portion.
You can use this to JOIN on to, which will restrict the output to rows with a matching date:
SELECT *
FROM YourTable t1
INNER JOIN ( SELECT DISTINCT TOP 7
CAST(TestDate AS DATE) DT
FROM YourTable
ORDER BY CAST(TestDate AS DATE) DESC
) dts ON dts.DT = CAST(t1.TestDate AS DATE)

SQL Server - Possible ways to find MAX and MIN in several records

I'm new to MSSQL and finding an elegant way to do with the followings.
I have a table called Order and the details are as follows.
orderID orderTime quantity total
*****************************************************************
1 4/1/2013 06:00:00 AM 3 300
2 4/1/2013 09:00:00 AM 1 100
3 4/2/2013 07:33:00 PM 2 265
4 4/3/2013 04:15:00 PM 1 65
*****************************************************************
Is it possible to give out the following output?
orderDate total
*******************
4/1/2013 400
4/3/2013 65
I tried to convert the orderTime into string and further group it but somehow I failed. I'm still working hard to find a way to achieve it.
I'm using SQL Server 2008.
Sure - you can convert the orderTime to a date datatype and group by that. Your output seems to indicate you want a SUM rather than MIn/MAX, but you can adjust w/ the appropriate aggregation:
select
convert(date, orderTime) as 'orderDate',
sum(total) as 'total',
min(total) as 'Min',
max(total) as 'Max'
from Order
group by convert(date, orderTime)
order by convert(date, orderTime)
You can convert the orderTime to the Date data type:
SELECT orderDate = CONVERT(Date, orderTime)
, total = SUM(total)
FROM dbo.Order (NOLOCK)
GROUP BY CONVERT(Date, orderTime)
ORDER BY orderDate;
This will return an output of:
orderDate total
*******************
4/1/2013 400
4/2/2013 265
4/3/2013 65
It depends on the data type of orderTime. You can convert it to a date field (with no time):
SELECT CAST(orderTime AS DATE), SUM(total)
FROM Table
GROUP by CAST(orderTime AS DATE);
--dmg

Resources