SSRS:How to return count of events per day for Month - sql-server

I have a table with the following information
ID,DateTime,EventType
1,6/5/2013 9:35:00,B
1,6/5/2013 9:35:24,A
2,6/5/2013 9:35:36,B
3,6/5/2013 9:36:11,D
2,6/5/2013 9:39:16,A
3,6/5/2013 9:40:48,B
4,7/5/2013 9:35:19,B
4,7/5/2013 9:35:33,A
5,7/5/2013 9:35:53,B
5,7/5/2013 9:36:06,D
6,7/5/2013 9:39:39,A
7,7/5/2013 9:40:28,B
8,8/5/2013 9:35:02,A
7,8/5/2013 9:35:08,A
8,8/5/2013 9:35:29,B
6,8/5/2013 9:36:39,B
I need to count how many times each day an event changed state as long as the time between states was less than 30 seconds over the time period.
Basically I am looking for the following result set
6/5/2013 | 1
7/5/2013 | 2
8/5/2013 | 1
I've tried several different types of queries, but nothing works. I am using SQL Server Reporting Services 2008.

declare #t table (ID int,[DateTime] datetime ,EventType varchar);
insert #t values
(1,'6/5/2013 9:35:00','B'),
(1,'6/5/2013 9:35:24','A'),
(2,'6/5/2013 9:35:36','B'),
(3,'6/5/2013 9:36:11','D'),
(2,'6/5/2013 9:39:16','A'),
(3,'6/5/2013 9:40:48','B'),
(4,'7/5/2013 9:35:19','B'),
(4,'7/5/2013 9:35:33','A'),
(5,'7/5/2013 9:35:53','B'),
(5,'7/5/2013 9:36:06','D'),
(6,'7/5/2013 9:39:39','A'),
(7,'7/5/2013 9:40:28','B'),
(8,'8/5/2013 9:35:02','A'),
(7,'8/5/2013 9:35:08','A'),
(8,'8/5/2013 9:35:29','B'),
(6,'8/5/2013 9:36:39','B');
--select * from #t order by ID, DateTime;
with cte as (
select *, cast([DateTime] as date) the_date, row_number() over (partition by ID order by DateTime) row_num
from #t
)
select c1.the_date, count(1)
from cte c1
join cte c2
on c2.ID = c1.ID
and c2.row_num = c1.row_num + 1
where datediff(S,c1.DateTime, c2.DateTime) < 30
group by c1.the_date
order by c1.the_date;

Try this:
select CONVERT(VARCHAR(10), a.DateTime, 103) [Date], count(a.ID) Count from Table a
inner join Table b on a.ID = b.ID
where DATEDIFF(second,a.DateTime,b.DateTime) between 1 and 29 and a.ID = b.ID
and Cast(a.DateTime as Date) = Cast(b.DateTime as date)
group by CONVERT(VARCHAR(10), a.DateTime, 103)

Related

SQL Query Get Last record Group by multiple fields

Hi I have a table with following fields:
ALERTID POLY_CODE ALERT_DATETIME ALERT_TYPE
I need to query above table for records in the last 24 hour.
Then group by POLY_CODE and ALERT_TYPE and get the latest Alert_Level value ordered by ALERT_DATETIME
I can get up to this, but I need the AlertID of the resulting records.
Any suggestions what would be an efficient way of getting this ?
I have created an SQL in SQL Server. See below
SELECT POLY_CODE, ALERT_TYPE, X.ALERT_LEVEL AS LAST_ALERT_LEVEL
FROM
(SELECT * FROM TableA where ALERT_DATETIME >= GETDATE() -1) T1
OUTER APPLY (SELECT TOP 1 [ALERT_LEVEL]
FROM (SELECT * FROM TableA where ALERT_DATETIME >= GETDATE() -1) T2
WHERE T2.POLY_CODE = T1.POLY_CODE AND
T2.ALERT_TYPE = T1.ALERT_TYPE ORDER BY T2.[ALERT_DATETIME] DESC) X
GROUP BY POLY_CODE, ALERT_TYPE, X.[ALERT_LEVEL]
POLY_CODE ALERT_TYPE ALERT_LEVEL
04575 Elec 2
04737 Gas 3
06239 Elec 2
06552 Elec 2
06578 Elec 2
10320 Elec 2
select top 1 with ties *
from TableA
where ALERT_DATETIME >= GETDATE() -1
order by row_number() over (partition by POLY_CODE,ALERT_TYPE order by [ALERT_DATETIME] DESC)
The way this works is that for each group of POLY_CODE,ALERT_TYPE get their own row_number() starting from the most recent alert_datetime. Then, the with ties clause ensures that all rows(= all groups) with the row_number value of 1 get returned.
One way of doing it is creating a cte with the grouping that calculates the latesdatetime for each and then crosses it with the table to get the results. Just keep in mind that if there are more than one record with the same combination of poly_code, alert_type, alert_level and datetime they will all show.
WITH list AS (
SELECT ta.poly_code,ta.alert_type,MAX(ta.alert_datetime) AS LatestDatetime,
ta.alert_level
FROM dbo.TableA AS ta
WHERE ta.alert_datetime >= DATEADD(DAY,-1,GETDATE())
GROUP BY ta.poly_code, ta.alert_type,ta.alert_level
)
SELECT ta.*
FROM list AS l
INNER JOIN dbo.TableA AS ta ON ta.alert_level = l.alert_level AND ta.alert_type = l.alert_type AND ta.poly_code = l.poly_code AND ta.alert_datetime = l.LatestDatetime

T-SQL: AGGREGATE AND/OR CONDITIONAL SUBQUERY ON WHERE CLAUSE

Thanks in advance for your help on this. Here's the the scenario. I have two tables: Lots (stores lot info for food items) and Trans (stores inventory transactions on lot items).
I am trying to write a query that lists all the transactions that are older than 90 days based 3 conditions on the where clause somehow:
CurrentQty (on Lots table) > 0
If TransactionType = Shipment AND TransactionDate > 90 days (from current date) OR..
IF TransactionType = Receipt AND TransactionDate > 90 days (from current date)
Notes: for each lot, there could be many different transactions of the same type, as shown in the attached picture. There could be many shipments or receipts. I need to be able to select the MAX(TransactionDate) for a particular transaction type and check to see if it's over 90 days then show the record.
There will always be at least one of these two transaction types on the transaction table for every lot, either Shipment or Receipt. If there is no shipment transaction type on a particular lot, then I want to use the Max(TransactionDate) > 90 condition for the "receipt" transaction type.
I need to be able to evaluate all these conditions for each lot and it's particular transactions.
Below is the query I started to write, but then got stuck on how to structure the rest.
SELECT
LOTS.LOTNUMBER, TRANS.ITEMNUMBER, TRANS.DESCRIPTION,
TRANS.TRANSACTIONTYPE, TRANS.TRANSACTIONDATE, TRANS.WAREHOUSE,
TRANS.QUANTITY
FROM
LOTS
INNER JOIN
TRANS ON LOTS.LOTNUMBER = TRANS.LOTNUMBER
WHERE
LOTS.CURRENTQUANTITY > 0
SELECT
LOTS.LOTNUMBER, TRANS.ITEMNUMBER, TRANS.DESCRIPTION,
TRANS.TRANSACTIONTYPE, TRANS.TRANSACTIONDATE, TRANS.WAREHOUSE,
TRANS.QUANTITY
FROM
LOTS
INNER JOIN
(Select LotNumber, Max(TransactionDate) MaxTransDate From TRANS Group By LotNumber) Trans ON LOTS.LOTNUMBER = TRANS.LOTNUMBER
WHERE
LOTS.CURRENTQUANTITY > 0 And
DATEDIFF(d, TRANS.TRANSACTIONDATE, getdate()) > 90 And
(TRANS.TRANSACTIONTYPE = 'Reciept' Or
TRANS.TRANSACTIONTYPE = 'Shipment')
DECLARE #lots TABLE (
LotNumber NVARCHAR(10)
,ItemNum NVARCHAR(12)
,CurrentQty INT
)
DECLARE #trans TABLE (
TransNum INT
,ItemNum NVARCHAR(12)
,Description NVARCHAR(30)
,TransType NVARCHAR(10)
,TransDate DATE
,Warehouse NVARCHAR(5)
,Quantity INT
)
INSERT INTO #lots VALUES
('ABC','10-MAND-5879',925)
INSERT INTO #trans VALUES
(398741,'10-MAND-5879','10 Lb Mandarin Bag','Receipt','2016-01-01','IXCST',100)
,(973541,'10-MAND-5879','10 Lb Mandarin Bag','Shipment','2016-02-04','WTGS',365)
,(972547,'10-MAND-5879','10 Lb Mandarin Bag','Receipt','2016-02-29','GKWK',250)
,(632403,'10-MAND-5879','10 Lb Mandarin Bag','Shipment','2016-03-01','GWSJ',150)
,(692147,'10-MAND-5879','10 Lb Mandarin Bag','Shipment','2016-03-17','ABTK',25)
;WITH MaxShip
AS (
SELECT ItemNum, TransNum,
ROW_NUMBER () OVER (PARTITION BY ItemNum ORDER BY TransDate DESC) AS TransOrder
FROM #trans
WHERE TransType = 'Shipment'
),
MaxRcpt
AS (
SELECT ItemNum, TransNum,
ROW_NUMBER () OVER (PARTITION BY ItemNum ORDER BY TransDate DESC) AS TransOrder
FROM #trans
WHERE transtype = 'Receipt'
)
SELECT *
FROM #trans t
LEFT JOIN #lots l
ON t.ItemNum = l.ItemNum
JOIN MaxShip ms
ON ms.TransNum = t.TransNum
WHERE TransOrder = 1 AND CurrentQty > 0 AND DATEADD(dd,90,TransDate) < GETDATE()
UNION
SELECT *
FROM #trans t
LEFT JOIN #lots l
ON t.ItemNum = l.ItemNum
JOIN MaxRcpt mr
ON mr.TransNum = t.TransNum
WHERE TransOrder = 1 AND CurrentQty > 0 AND DATEADD(dd,90,TransDate) < GETDATE()

Multiple value IF statement, to show in select

Any help appreciated,
the code below is from a database which someone made, every time a receipt is made a unique receipt id is issued. same when a reversal is made a new receipt is issued. what links the two are the pay in number. If a reverse is issued, the reverse flag changes on the old receipt to Y and the new one says N. i have my query that select Minimum date and Max data, for receipts returned will have a much later date that when it was first created. The issue is when there is no reverse, it still pulls information as the min and max date are the same. I am fully aware that i need an if statement, but have no idea how to do it since i am new to Databases.
Select distinct r.receipt_date, r.receipt_no, r.doc_no as Payin_No,r.trans_amt,l.location_desc, ct.charge_type_desc,
(select un.first_name + ' ' + un.last_name)as cashier,
r.payee, r.comments, r.reverse_flag, ret1.returned_by, ret1.return_date
from Cashier..receipts as r
inner join Cashier..location as l on r.location_id=l.location_id
inner join [Cashier].[dbo].[charge_type] as ct on ct.charge_type_no=r.charge_type_no
inner join Cashier..user_name as un on un.user_name=(UPPER(r.created_by))
inner join (
select receipt_no as Return_Receipt ,
(select un2.first_name + ' ' + un2.last_name) as returned_by,
created_date as return_date, doc_no as Payin_no,
r1.reverse_flag
from Cashier..receipts as r1
inner join Cashier..user_name as un2 on un2.user_name=(UPPER(r1.created_by))
where doc_no = r1.doc_no
and created_date = (select MAX(created_date)
from Cashier..receipts where doc_no = r1.doc_no)) as ret1
on (ret1.Payin_no=r.doc_no)
where r.receipt_date = (select MIN(r1.receipt_date) from Cashier..receipts as r1 where r1.receipt_no = r.receipt_no )
Issue i am having, the return by is the same as created
Desired result
Is this basically what you're trying to do?
-- test data creation, for me
create table receipts (receipt_no int, receipt_date datetime, doc_no int, reverse_flag char(1), returned_by varchar(10), create_date datetime, created_date datetime)
insert into receipts values (1, '1/1/2016', 12345, 'Y', 'John', null, '1/1/2016')
insert into receipts values (2, '2/15/2016', 12345, 'N', null, '2/15/2016', '2/15/2016')
SELECT r.receipt_date, r.receipt_no, r.doc_no, r.reverse_flag, ret1.return_date
FROM receipts r
INNER JOIN (
SELECT doc_no, create_date as return_date
FROM receipts
WHERE reverse_flag = 'N')ret1 on r.doc_no = ret1.doc_no and ret1.return_date > r.receipt_date
WHERE r.reverse_flag = 'Y' and r.doc_no = 12345
If that's your goal, I think you just tack this on to the very end of your query:
and r.receipt_date < ret1.return_date
Edit: Based on your update, I think tack this onto the end:
and convert(date, r.receipt_date) < convert(date, ret1.return_date)
I'm still really not sure what you want.
select *
from ( select doc_no, min(receipt_date) as min_receipt_date
from receipts group by doc_no ) as min_receipt
left outer join ( select doc_no, max(receipt_date) as max_receipt_date
from receipts group by doc_no) as max_receipt
on min_receipt.doc_no = max_receipt.doc_no and
min_receipt.min_receipt_date <> max_receipt.max_receipt_date
for
insert into receipts values (1, '2016-01-01', 12345, 'Y', 'John', null, '2016-01-01');
insert into receipts values (2, '2016-03-15', 12345, 'N', null, '2016-03-15', '2016-03-15');
insert into receipts values (3, '2016-03-15', 123667, 'N', null, '2016-03-15', '2016-03-15');
yields
doc_no min_receipt_date doc_no max_receipt_date
12345 January, 01 2016 00:00:00 12345 March, 15 2016 00:00:00
123667 March, 15 2016 00:00:00 (null) (null)
but it assumes that the return date will never be the same as the original receipt date. I also left off the Y and N flags because I don't see how it's necessary if the min date is always the original purchase date. The other answer here uses the created_date but in your screenshot of the table data, you only show one date so I wrote it assuming only one date (the receipt date). I tested that on MySQL because SQLFiddle was hating on my SQL Server syntax for inserts and I don't have another way to test right now.
This is what i was looking for, figured it out. Thank you Max for opening insights on how i could tackle the problem.
Select distinct r.receipt_date, r.receipt_no, r.doc_no as Payin_No,r.trans_amt,l.location_desc, ct.charge_type_desc,
(select un.first_name + ' ' + un.last_name)as cashier,
r.payee, r.comments, r.cost_centre, r.item, r.programme, r.activity, r.btl_sof, r.reverse_flag, --, ret1.returned_by, ret1.return_date
(case when r.reverse_flag = 'Y' then (select (un2.first_name + ' ' + un2.last_name)from Cashier..receipts as r1
inner join Cashier..user_name as un2 on un2.user_name=(UPPER(r1.created_by)) where created_date = (select MAX(created_date)
from Cashier..receipts where doc_no = r.doc_no)) end ) as returned_by ,
(case when r.reverse_flag = 'Y' then (select created_date from Cashier..receipts as r1
inner join Cashier..user_name as un2 on un2.user_name=(UPPER(r1.created_by)) where created_date = (select MAX(created_date)
from Cashier..receipts where doc_no = r.doc_no)) end ) as returned_date
from Cashier..receipts as r
inner join Cashier..location as l on r.location_id=l.location_id
inner join [Cashier].[dbo].[charge_type] as ct on ct.charge_type_no=r.charge_type_no
inner join Cashier..user_name as un on un.user_name=(UPPER(r.created_by))
where r.receipt_date = (select MIN(r1.receipt_date) from Cashier..receipts as r1 where r1.receipt_no = r.receipt_no )

MS SQL Query min/max/average per day

I have a query:
WITH cte AS(
SELECT T3.DateTime AS AADateTime,
(T3.In_Minbps/1000)/1000 AS MinReceiveMbps,
(T3.In_Maxbps/1000)/1000 AS MaxReceiveMbps,
(T3.In_Averagebps/1000)/1000 AS AvgReceiveMbps,
(T3.Out_Minbps/1000)/1000 AS MinTransmitMbps,
(T3.Out_Maxbps/1000)/1000 AS MaxTransmitMbps,
(T3.Out_Averagebps/1000)/1000 AS AvgTransmitMbps
FROM dbo.Nodes AS T1
INNER JOIN dbo.Interfaces AS T2 ON [T1].[NodeID] = [T2].[NodeID]
INNER JOIN InterfaceTraffic AS T3 ON [T2].[InterfaceID] = [T3].[InterfaceID]
WHERE [T1].[Caption] = 'cust-firewall01'
AND [T2].[InterfaceName] = 'reth0'
AND DateTime >= '2014-08-01 00:00:00' AND DateTime <= '2014-08-31 23:59:59'
)
SELECT MIN(AADateTime) AS AADateTime,
MIN(MinReceiveMbps) AS MinReceiveMbps,
MAX(MaxReceiveMbps) AS MaxReceiveMbps,
MIN(MinTransmitMbps) AS MinTransmitMbps,
MAX(MaxTransmitMbps) AS MaxTransmitMbps,
AVG(AvgTransmitMbps) AS AvgTransmitMbps,
AVG(AvgReceiveMbps) AS AvgReceiveMbps
FROM cte
The above query works however returns an min/max/average of all records, what I need to do is return min/max/average per day. example table data is:
Date, In_Minbps, In_Maxbps, In_Averagebps, Out_Minbps, Out_Maxbps, Out_Averagebps
2014-08-01 00:00:00, 403227.2, 3489988, 1986171, 6509198, 6.510824e+07, 33357.06
2014-08-01 01:00:00, 404039.1, 3626866, 2211984, 4491261, 6.61291e+07, 37061.19
there are basically 24 records per day I need this per day:
SELECT MIN(AADateTime) AS AADateTime,
MIN(MinReceiveMbps) AS MinReceiveMbps,
MAX(MaxReceiveMbps) AS MaxReceiveMbps,
MIN(MinTransmitMbps) AS MinTransmitMbps,
MAX(MaxTransmitMbps) AS MaxTransmitMbps,
AVG(AvgTransmitMbps) AS AvgTransmitMbps,
AVG(AvgReceiveMbps) AS AvgReceiveMbps
FROM cte
SELECT CAST(Datetimefield AS DATE) AS Date,
MIN(MinReceiveMbps) AS MinReceiveMbps,
MAX(MaxReceiveMbps) AS MaxReceiveMbps,
MIN(MinTransmitMbps) AS MinTransmitMbps,
MAX(MaxTransmitMbps) AS MaxTransmitMbps,
AVG(AvgTransmitMbps) AS AvgTransmitMbps,
AVG(AvgReceiveMbps) AS AvgReceiveMbps
FROM cte
GROUP BY CAST(Datetimefield AS DATE)
Its group by date your records.

LASt 6 records of the output of the stored procedure

The following is the stored procedure and "I want to fetch the LATEST SIX
INVOICES FOR EACH CUSTOMER"
THERE COULD BE MORE INVOICES FOR EACH CUSTOMER BUT I HAVE TO FETCH ONLY
WHICH ARE LATEST 6 INVOICES.
ALTER PROCEDURE [dbo].[SCA_M_CUSTSOINV_REFRESH]
#COMP_CD NVARCHAR(20)='',
#USER_CD NVARCHAR(20)='',
#USER_TYPE NVARCHAR(1)=''
AS
SET NOCOUNT ON
DECLARE #SLSHIST_DATE NVARCHAR(10)
SELECT
#SLSHIST_DATE = CONVERT(NVARCHAR(10), DATEADD(MONTH,-SLSHIST_MTH,dbo.[GetCountryDate]()),120)
FROM SET_MASTER
WITH SUBQUERY AS
(SELECT
ROW_NUMBER() OVER (PARTITION BY A.CUST_CD ORDER BY C.INV_KEY DESC) "ROW_ID",
A.CUST_CD,C.SO_KEY "TXN_KEY",
C.INV_NO, C.INV_KEY, C.INV_DT, C.INV_STATUS, C.NET_TTL_TAX AS INV_AMT
FROM
(SELECT DIST_CD, SLSMAN_CD, CUST_CD FROM T_CA_SLSMANCUST
WHERE DIST_CD = #COMP_CD AND SLSMAN_CD = #USER_CD) A
INNER JOIN TXN_INVOICE C ON C.CUST_CD=A.CUST_CD
AND C.INV_DT >= #SLSHIST_DATE
)
SELECT
CUST_CD, TXN_KEY, INV_NO, INV_KEY, INV_DT, INV_STATUS, INV_AMT,
CASE ROW_ID WHEN 1 THEN 'Y' ELSE 'N' END "LAST_INV"
FROM SUBQUERY
ORDER BY CUST_CD,INV_KEY
You are getting ROW_ID by ROW_NUMBER() OVER (PARTITION BY A.CUST_CD ORDER BY C.INV_KEY DESC) and the last invoice is the one with ROW_ID = 1 so don't you just need to add WHERE ROW_ID <= 6 as below?
SELECT
CUST_CD, TXN_KEY, INV_NO, INV_KEY, INV_DT, INV_STATUS, INV_AMT,
CASE ROW_ID WHEN 1 THEN 'Y' ELSE 'N' END "LAST_INV"
FROM SUBQUERY
WHERE ROW_ID <= 6
ORDER BY CUST_CD,INV_KEY
SELECT TOP 6 * FROM invoices ORDER BY date DESC

Resources