This is my table:
with these columns:
ShiftId ShiftNum Date ShiftType StartTime EndTime
1 1 2014-08-07 A 0:00:00 6:00:00
2 2 2014-08-07 B 6:01:00 18:00:00
3 3 2014-08-07 A 18:00:01 23:59:00
4 1 2014-08-08 A 0:00:00 6:00:00
5 2 2014-08-08 C 6:01:00 18:00:00
6 3 2014-08-08 B 18:00:01 23:59:00
7 1 2014-08-09 B 0:00:00 6:00:00
8 2 2014-08-09 C 6:01:00 18:00:00
9 3 2014-08-09 B 18:00:01 23:59:00
10 1 2014-08-10 B 0:00:00 6:00:00
11 2 2014-08-10 D 6:01:00 18:00:00
12 3 2014-08-10 C 18:00:01 23:59:00
13 1 2014-08-11 C 0:00:00 6:00:00
14 2 2014-08-11 D 6:01:00 18:00:00
15 3 2014-08-11 C 18:00:01 23:59:00
16 1 2014-08-12 C 0:00:00 6:00:00
17 2 2014-08-12 A 6:01:00 18:00:00
18 3 2014-08-12 D 18:00:01 23:59:00
19 1 2014-08-13 D 0:00:00 6:00:00
20 2 2014-08-13 A 6:01:00 18:00:00
21 3 2014-08-13 D 18:00:01 23:59:00
22 1 2014-08-14 D 0:00:00 6:00:00
23 2 2014-08-14 B 6:01:00 18:00:00
I want to add "DailyShiftId" column as computrd column means when shiftType changed then DailyShiftId has been increased.
ShiftId ShiftNum Date ShiftType StartTime EndTime DailyShiftId
1 1 2014-08-07 A 0:00:00 6:00:00 1
2 2 2014-08-07 B 6:01:00 18:00:00 2
3 3 2014-08-07 A 18:00:01 23:59:00 3
4 1 2014-08-08 A 0:00:00 6:00:00 3
5 2 2014-08-08 C 6:01:00 18:00:00 4
6 3 2014-08-08 B 18:00:01 23:59:00 5
7 1 2014-08-09 B 0:00:00 6:00:00 5
8 2 2014-08-09 C 6:01:00 18:00:00 6
9 3 2014-08-09 B 18:00:01 23:59:00 7
10 1 2014-08-10 B 0:00:00 6:00:00 7
11 2 2014-08-10 D 6:01:00 18:00:00 8
12 3 2014-08-10 C 18:00:01 23:59:00 9
13 1 2014-08-11 C 0:00:00 6:00:00 9
14 2 2014-08-11 D 6:01:00 18:00:00 10
15 3 2014-08-11 C 18:00:01 23:59:00 11
16 1 2014-08-12 C 0:00:00 6:00:00 11
17 2 2014-08-12 A 6:01:00 18:00:00 12
18 3 2014-08-12 D 18:00:01 23:59:00 13
19 1 2014-08-13 D 0:00:00 6:00:00 13
20 2 2014-08-13 A 6:01:00 18:00:00 14
21 3 2014-08-13 D 18:00:01 23:59:00 15
22 1 2014-08-14 D 0:00:00 6:00:00 15
23 2 2014-08-14 B 6:01:00 18:00:00 16
how can I do it?
Create On Update Trigger
CREATE TRIGGER ViewEmployeeTrigger ON Employee
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON
UPDATE Employee
SET DailyShiftId=DailyShiftId+1
-- what ever your updation logic
FROM INSERTED I JOIN Employee C ON I.ShiftId= C.ShiftId
END
GO
You can add DailyShiftId as a normal column and add an AFTER UPDATE Trigger on your table:
CREATE TRIGGER TAU_MyTable
ON MyTable
AFTER UPDATE
AS
BEGIN
UPDATE MyTable SET DailyShiftId = DailyShiftId + 1
WHERE [INSERTED].ShiftType <> [DELETED].ShiftType
END
OR
You can add a function to the database to calculate value of the new column and use Computed Column Specification as done here:
http://www.c-sharpcorner.com/UploadFile/rohatash/formula-for-computed-column-specification-property-in-sql-se/
This Query will be helpful to you to get the expected result without using trigger.
DECLARE #Test Table
(
ShiftId Integer,
ShiftNum Int,
Date DATETIME,
ShiftType VARCHAR(1)
)
INSERT INTO #Test (ShiftId, ShiftNum, Date, ShiftType)
SELECT 1, 1, '2014-08-07', 'A' UNION ALL
SELECT 2, 2, '2014-08-07', 'B' UNION ALL
SELECT 3, 3, '2014-08-07', 'A' UNION ALL
SELECT 4, 1, '2014-08-08', 'A' UNION ALL
SELECT 5, 2, '2014-08-08', 'C' UNION ALL
SELECT 6, 3, '2014-08-08', 'B' UNION ALL
SELECT 7, 1, '2014-08-09', 'B'
SELECT C.ShiftId, C.ShiftNum, C.Date, C.ShiftType ,
DENSE_RANK() OVER( order by C.DailyShift ASC) AS DailyShift
FROM
(
SELECT A.*,
CASE WHEN A.ShiftType = B.ShiftType
Then ROW_NUMBER() OVER(ORDER BY A.ShiftId ASC) - 1
Else ROW_NUMBER() OVER(ORDER BY A.ShiftId ASC)
END AS DailyShift
FROM #Test AS A LEFT JOIN #Test AS B ON A.ShiftId = B.ShiftId + 1
) AS C
Using Computed Column:
Add the column to the table specifing the function (Calculate).
ALTER TABLE dbo.TableName
ADD DailyShiftID AS dbo.Calculate(ShiftId, ShiftType)
CREATE FUNCTION dbo.Calculate(#nShiftId INT, #sShiftType VARCHAR(1))
RETURNS INT
AS
BEGIN
DECLARE #sPrevShiftType AS VARCHAR(1)
DECLARE #nDailyShift AS INT
SELECT #sPrevShiftType = ShiftType, #nDailyShift = ISNULL(DailyShiftID, 0)
FROM TableName WHERE ShiftId = #nShiftId - 1
IF (#sPrevShiftType <> #sShiftType)
SET #nDailyShift = #nDailyShift + 1
RETURN #nDailyShift
END
Related
I have a Table 'Meter1' in my MSSQL database DB_TEST. Table structure is like this,
MeterID
Timestamp
Value
7
2022-09-16 11:00:00.000
1800
7
2022-09-16 12:00:00.000
1805
7
2022-09-16 13:00:00.000
1820
7
2022-09-16 14:00:00.000
1860
7
2022-09-16 15:00:00.000
1875
I need to calculate the hourly consumption by substracting the current value - previous value.
I have achieved this by using LAG function,
SELECT [MeterID]
,[Timestamp]
,[Value]
,VALUE - LAG (VALUE)
OVER (ORDER BY TIMESTAMP) AS Consumption
FROM [DB_TEST].[dbo].[Meter1]
& the results like this
MeterID
Timestamp
Value
Consumption
7
2022-09-16 11:00:00.000
1800
NULL
7
2022-09-16 12:00:00.000
1805
5
7
2022-09-16 13:00:00.000
1820
15
7
2022-09-16 14:00:00.000
1860
40
7
2022-09-16 15:00:00.000
1875
15
But how can I update or Insert the same results to my existing table with another column "Consumption".
First I'm using AdventureWork2019 as a reference
I have a query where I'm joining 5 Tables
USE [AdventureWorks2019]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Alter PROCEDURE dbo.TestLocation
#UseDate DateTime
AS
BEGIN
SET NOCOUNT ON;
SELECT prodID
,SUM(PurchQty) AS TotalPurchase
,SUM(SalesQty) AS TotalSell
,StartDate
from (
SELECT DISTINCT WO.ProductID AS prodID
, StartDate
,WO.OrderQty AS PurchQty
,SOD.OrderQty AS SalesQty
FROM Sales.SalesOrderDetail SOD
LEFT JOIN Production.WorkOrderRouting WOR ON WOR.ProductID = SOD.ProductID
--LEFT JOIN Production.Location PL ON PL.LocationID = WOR.LocationID
--The above Join is the one for the locationID and it's working Fine
LEFT JOIN Production.WorkOrder WO ON WO.ProductID = SOD.ProductID
FULL OUTER JOIN Purchasing.PurchaseOrderDetail POD ON POD.ProductID = SOD.ProductID
WHERE StartDate = #UseDate
-- AND PL.LocationID >= 10
) Test3
Group by prodID,StartDate
order by prodID ASC, StartDate
END
GO
EXEC TestLocation '2011-07-02 00:00:00.000'
Output(sample):
prodID TotalPurc TotalSell StartDate
717 8 36 2011-07-02 00:00:00.000
730 9 47 2011-07-02 00:00:00.000
744 2 3 2011-07-02 00:00:00.000
747 12 21 2011-07-02 00:00:00.000
749 5 15 2011-07-02 00:00:00.000
761 16 138 2011-07-02 00:00:00.000
775 26 91 2011-07-02 00:00:00.000
777 12 78 2011-07-02 00:00:00.000
802 6 21 2011-07-02 00:00:00.000
804 40 60 2011-07-02 00:00:00.000
806 16 138 2011-07-02 00:00:00.000
807 24 23 2011-07-02 00:00:00.000
810 21 28 2011-07-02 00:00:00.000
811 6 21 2011-07-02 00:00:00.000
813 8 37 2011-07-02 00:00:00.000
817 21 28 2011-07-02 00:00:00.000
And another Table For LocationID (as a warehouse)
SELECT LocationID,CostRate,Availability
FROM Production.Location
WHERE LocationID >= 10
order by CostRate ASC
LocationID CostRate Availability
50 12.25 120.00
60 12.25 120.00
30 14.50 120.00
40 15.75 120.00
45 18.00 80.00
10 22.50 96.00
20 25.00 108.00
What I want to do is to take each LoactionId and ProdID and take TotalPurc to the location and decrement the quantity in the Availability column, each TotalSell will increment the Availability column. The max Availability quantity is 130.
If all locations have no Available quantity that is the Available is 0 for all locations then it will stop.
the above will work with the date specified as you can check the query and run it if you have
AdventureWork2019
simple output to check how I want the data to be:
prodID TotalPurc TotalSell StartDate
717 8 36 2011-07-02 00:00:00.000
730 9 47 2011-07-02 00:00:00.000
744 2 3 2011-07-02 00:00:00.000
747 12 21 2011-07-02 00:00:00.000
749 5 15 2011-07-02 00:00:00.000
LocationID CostRate Availability
50 12.25 120.00
60 12.25 120.00
30 14.50 120.00
40 15.75 120.00
45 18.00 80.00
10 22.50 96.00
20 25.00 108.00
Output :
prodID TotalPurc TotalSell StartDate LocationID Availability Remaining
717 8 36 2011-07-02 00:00:00.000 50 130 18
717 8 36 2011-07-02 00:00:00.000 60 130 8
717 8 36 2011-07-02 00:00:00.000 30 128 0
--what happened above is that I took the (120-8) = 112 then 112+36 = 148 we only can use 130 then the remaining is 18 then we took the next `LocationID` with the least Cost (120+18 = 138 we can use 130 so we took the 8) and used it in the next `LocationID`
730 9 47 2011-07-02 00:00:00.000 30 130 36
730 9 47 2011-07-02 00:00:00.000 40 130 26
730 9 47 2011-07-02 00:00:00.000 45 106 0
744 2 3 2011-07-02 00:00:00.000 45 107 0
747 12 21 2011-07-02 00:00:00.000 45 116 0
749 5 15 2011-07-02 00:00:00.000 45 126 0
--the above is the same as the first 3 rows we subtract and add to the availability
The other condition is that if all locations reached 0 or 130 then stop
How can I do that in SQL Server? I tried using CTE but didn't work well with me and tried the cursor which I think is the best for this kind of thing but didn't achieve anything.
Thank you in advance
Edit :
ALTER FUNCTION GetStockMovment
(
-- Add the parameters for the function here
#ForDate Datetime
)
RETURNS #Sums TABLE (
RemoveQTY Numeric(24, 7),
ADDQTY Numeric(24, 7)
)
AS
BEGIN
Declare #WoSum Numeric(24, 7),
#SODSUM Numeric(24, 7),
#WORSum Numeric(24, 7),
#PODSum Numeric(24, 7)
select #SODSUM = SUM(SOD.OrderQty) from Sales.SalesOrderDetail SOD
INNER JOIN Sales.SalesOrderHeader SOH ON SOD.SalesOrderID = SOH.SalesOrderID
where SOH.OrderDate = #ForDate
select #WoSum = sum(orderQty) from Production.WorkOrder
where StartDate = #ForDate
select #PODSum = sum(POD.OrderQty) from Purchasing.PurchaseOrderDetail POD
INNER JOIN Purchasing.PurchaseOrderHeader POH ON POD.PurchaseOrderID = POH.PurchaseOrderID
where POH.OrderDate = #ForDate
select #WoSum = sum(WO.OrderQty) from Production.WorkOrder WO
where WO.DueDate = #ForDate
INSERT INTO #Sums (RemoveQTY,ADDQTY)
SELECT isnull(#SODSUM,0) + isnull(#WORSum,0) , isnull(#PODSum,0) + isnull(#WoSum,0)
RETURN;
END;
GO
select * from dbo.GetStockMovment ('2014-05-26 00:00:00.000')
Output:
RemoveQTY ADDQTY
189.0000000 5334.0000000
You should use LAG or LEAD function.
https://learn.microsoft.com/en-us/sql/t-sql/functions/lead-transact-sql?view=sql-server-ver15
https://learn.microsoft.com/en-us/sql/t-sql/functions/lag-transact-sql?view=sql-server-ver15
I have a SQL query where I am getting the row number for a count of employees per division and per month at the beginning of the month and the end of the month. To do that, I use a payroll end date which is a weekly date. So in essence I have 4 dates where employee counts are shown. Some months have 5 dates which makes the row count for that month 5 instead of 4.
I then need to build an SSRS report to show only the first employee count and the last employee count per division, per month. I have the first number since I am using =IIF(Fields!RowNumber.Value = 1, Fields!EMPCOUNT.Value, 0)
The problem I have now is getting the last employee count where I need to conditionally select a count where row number needs to be 5 if exists or 4 if it doesn't exist. I'm not sure how to get the expression to work in SSRS. Sample data is below.
PRCo EMPCOUNT udDivision PREndDate ROWNUM Type
1 89 Civil 2018-01-06 00:00:00 1 1
1 97 Civil 2018-01-13 00:00:00 2 1
1 97 Civil 2018-01-20 00:00:00 3 1
1 97 Civil 2018-01-27 00:00:00 4 1
1 16 Colorado 2018-01-06 00:00:00 1 1
1 18 Colorado 2018-01-13 00:00:00 2 1
1 14 Colorado 2018-01-20 00:00:00 3 1
1 10 Colorado 2018-01-27 00:00:00 4 1
1 94 Civil 2018-02-03 00:00:00 1 2
1 91 Civil 2018-02-10 00:00:00 2 2
1 92 Civil 2018-02-17 00:00:00 3 2
1 91 Civil 2018-02-24 00:00:00 4 2
1 16 Colorado 2018-02-03 00:00:00 1 2
1 16 Colorado 2018-02-10 00:00:00 2 2
1 18 Colorado 2018-02-17 00:00:00 3 2
1 19 Colorado 2018-02-24 00:00:00 4 2
1 92 Civil 2018-03-03 00:00:00 1 3
1 91 Civil 2018-03-10 00:00:00 2 3
1 88 Civil 2018-03-17 00:00:00 3 3
1 92 Civil 2018-03-24 00:00:00 4 3
1 90 Civil 2018-03-31 00:00:00 5 3
1 19 Colorado 2018-03-03 00:00:00 1 3
1 26 Colorado 2018-03-10 00:00:00 2 3
1 25 Colorado 2018-03-17 00:00:00 3 3
1 27 Colorado 2018-03-24 00:00:00 4 3
1 24 Colorado 2018-03-31 00:00:00 5 3
I would do this in your query rather than trying to get it to work directly in SSRS. There might be a simpler way than this but this is just based on your existing query.
Please note this is untested and just off the top of my head so it may need some editing before it will work.
SELECT * INTO #t FROM YOUR_EXISTING_QUERY
SELECT DISTINCT
PRCo
, udDivision
, YEAR(PREndDate) AS Yr
, MONTH(PREndDate) AS Mnth
, FIRST_VALUE(EMPCOUNT) OVER(PARTITION BY PRCo, udDivision, YEAR(PREndDate), MONTH(PREndDate) ORDER BY ROWNUM) AS OpeningEMPCOUNT
, LAST_VALUE(EMPCOUNT) OVER(PARTITION BY PRCo, udDivision, YEAR(PREndDate), MONTH(PREndDate) ORDER BY ROWNUM) AS CLosing_EMPCOUNT
FROM #t
Yo might need to include Type not sure what this does but you get the idea hopefully.
The FIRST_VALUE and LAST_VALUE functions simply get the first/last value within the partition defined, in your case PRCo, udDivision and then just the year and month portion of the payroll end date, the first and last positions are determined by the order clause, in this case row number.
SELECT
t0.brandID,
t0.brandName,
t0.cdt,
t0.udt,
t0.brandstatus,
(DATEPART(MINUTE, t0.cdt)) as tempt
FROM brands t0
WHERE
CONVERT(VARCHAR(10),t0.cdt,110) BETWEEN
CONVERT(VARCHAR(10),'01-11-2013',110) and CONVERT(VARCHAR(10),'11-11-2014',110)
The above query giving me values between the dates. I want to get values between these dates for every 10 minutes.
brandID brandName cdt udt brandstatus tempt
1 khasim 2013-11-01 19:14:18.123 2013-11-15 19:14:18.123 1 14
3 khasim 2013-11-02 19:17:57.700 2013-11-15 19:17:57.700 1 17
4 tanveer 2013-11-03 19:18:05.947 2013-11-15 19:18:05.947 1 18
5 abcdef 2013-11-04 20:50:06.783 2013-11-15 20:50:06.787 1 50
8 budwieser 2014-02-12 19:26:43.913 2014-02-12 19:26:43.913 1 26
expected result: (when selecting date between 15-11-2013 and 16-11-2013)
brandid brandname cdt udt
1 khasim 2013-11-15 (00:00:01)---first record created on that date
2 somethi 2013-11-15 (00:00:05)---second record
...
...
final record at (00:10:00) minutes...
need to calculate number of 10 minute intervals between selected date and for every 10 min interval need to get records.
Before Start
I Have View 'PageViewModSession'
its code is
SELECT CONVERT(datetime, CONVERT(varchar(14), VisitStartDateTime) + ':00:00') AS DateValue, MAX(dbo.PageLogGroupByDateTimeFull(VisitStartDateTime)) AS PageLogCount,
(CASE MAX(dbo.SessionGroupByDateTimeFull(VisitStartDateTime)) WHEN 0 THEN 1 ELSE MAX(dbo.SessionGroupByDateTimeFull(VisitStartDateTime)) END) AS SessionLogCount, SiteInfoID
FROM dbo.PageLog
GROUP BY CONVERT(varchar(14), VisitStartDateTime), SiteInfoID
and When select this views my result is
and when select in ef with this syntaxt
var obj = db.PageViewModSessions.AsQueryable();
result is
repeat row one in every row on result
i catch created Sql query query in profiler
SELECT
[Extent1].[DateValue] AS [DateValue],
[Extent1].[PageLogCount] AS [PageLogCount],
[Extent1].[SessionLogCount] AS [SessionLogCount],
[Extent1].[SiteInfoID] AS [SiteInfoID]
FROM (SELECT
[PageViewModSession].[DateValue] AS [DateValue],
[PageViewModSession].[PageLogCount] AS [PageLogCount],
[PageViewModSession].[SessionLogCount] AS [SessionLogCount],
[PageViewModSession].[SiteInfoID] AS [SiteInfoID]
FROM [dbo].[PageViewModSession] AS [PageViewModSession]) AS [Extent1]
and result is
2015-11-03 01:00:00.000 19 9 2
2015-11-03 02:00:00.000 19 4 2
2015-11-03 03:00:00.000 4 1 2
2015-11-03 11:00:00.000 7 5 2
2015-11-03 12:00:00.000 9 2 2
2015-11-04 01:00:00.000 1 1 2
2015-11-04 02:00:00.000 12 1 2
2015-11-04 03:00:00.000 5 1 2
2015-11-04 05:00:00.000 1 1 2
2015-11-04 06:00:00.000 4 1 2
2015-11-04 10:00:00.000 20 2 2
2015-11-04 11:00:00.000 19 4 2
2015-11-04 12:00:00.000 23 18 2
2015-11-05 02:00:00.000 1 1 2
2015-11-05 03:00:00.000 5 1 2
2015-11-05 04:00:00.000 25 2 2
2015-11-05 10:00:00.000 2 1 2
2015-11-05 11:00:00.000 3 1 2
why ?!!
and what have to do fix this problem
I handle This
by Setting Two Key for model
DateValueand SiteInfoId