SSRS - Cannot read the next row for dataset DataSet1 - sql

with TotCFS as (select count(*)*1.0 as TotalCFS,
'Total CFS' as RowTitle
from PrivilegeData.TABLENAMEC c
where cast(CallCreatedDateTime as date) between #StartDate and #EndDate and CallPriority in ('1', '2', '3', '4', '5') and AreaCommand in ('FH', 'VA', 'NE', 'NW', 'SE', 'SW') and IsBolo = 0
)
select AreaCommand, CallPriority,
avg(datediff(second, CallCreatedDateTime, CallEntryDateTime)) as AverageSeconds,
left(dbo.[ConvertTimeToHHMMSS](avg(datediff(second, CallCreatedDateTime, CallEntryDateTime)), 's'), 7) as DisplayAvg,
'Create to Entry' as RowTitle, 1 as RowSort, b.SortOrder as ColumnSort
from PrivilegeData.TABLENAMEC c
inner join (select distinct AreaCommandAbbreviation, SortOrder from dimBeat) b on c.AreaCommand = b.AreaCommandAbbreviation
where cast(CallCreatedDateTime as date) between #StartDate and #EndDate and CallPriority in ('1', '2', '3', '4', '5') and AreaCommand in ('FH', 'VA', 'NE', 'NW', 'SE', 'SW') and IsBolo = 0
group by AreaCommand, CallPriority, SortOrder
UNION
select AreaCommand, CallPriority,
avg(datediff(second, CallEntryDateTime, CallDispatchDateTime)) as AvgEntryToDispatchSeconds,
left(dbo.ConvertTimeToHHMMSS(avg(datediff(second, CallEntryDateTime, CallDispatchDateTime)), 's'), 7) as DisplayAvgEntryToDispatchSeconds,
'Entry to Dispatch' as RowTitle, 2 , b.SortOrder
from PrivilegeData.TABLENAMEC c
inner join (select distinct AreaCommandAbbreviation, SortOrder from dimBeat) b on c.AreaCommand = b.AreaCommandAbbreviation
where cast(CallCreatedDateTime as date) between #StartDate and #EndDate and CallPriority in ('1', '2', '3', '4', '5') and AreaCommand in ('FH', 'VA', 'NE', 'NW', 'SE', 'SW') and IsBolo = 0
group by AreaCommand, CallPriority, SortOrder
I have about 8 unions I'm doing for this code. the difference is the name of the Row titles. this report has been running for about a year without any problems. I use this code in SSRS query type text. I also have one of my rowset name 'AverageSeconds' configured to read this expression
=IIf((Fields!RowSort.Value) < 7,Format(DateAdd("s", Avg(Fields!AverageSeconds.Value), "00:00:00"), "H:mm:ss"), Sum(Fields!AverageSeconds.Value))
the report some how broke and I have tried everything I find searching to fix it. Please help me with this error 'rsErrorReadingNextDataRow'.

This has got to be an issue with the data being operated upon. Maybe a 0 or NULL value condition.. I would start with reviewing records that were added or changed around the time that the problem began.

I Dropped and recreated the fact table and run my ssis package, which seams to fix it. The reason I did that is because I couldn't find a NULL or 0 value.

Related

Find third last event in table - Incomplete output

As my research into Firebird continues, I've attempted to improve some of my queries. As I use Libreoffice Base, I'm not 100% sure how the data entry code works, but I believe it's something like this:
CREATE TABLE "Data Entry"(
ID int,
Date date,
"Vehicle Type" varchar,
events int,
"Hours 1" int,
"Hours 2" int
);
INSERT INTO "Data Entry" VALUES
(1, '31/12/22', 'A', '1', '0', '1'),
(2, '31/12/22', 'A', '1', '0', '1'),
(3, '29/12/22', 'A', '3', '0', '1'),
(4, '25/06/22', 'B1', '1', '0', '1'),
(5, '24/06/22' , 'B1', '1', '1', '0'),
(6, '24/06/22' , 'B1', '1', '1', '0'),
(7, '31/12/22' , 'B2', '7', '0', '1'),
(8, '29/12/22' , 'C', '1', '0', '1'),
(9, '29/12/22' , 'C', '2', '0', '1'),
(10, '19/01/22' , 'D1', '5', '1', '0'),
(11, '23/01/22' , 'D2', '6', '1', '1'),
(12, '29/07/19' , 'D3', '5', '0', '1'),
(13, '21/12/22' , 'D4', '1', '0', '1'),
(14, '19/12/22' , 'D4', '1', '1', '1'),
(15, '19/12/22' , 'D4', '1', '0', '1'),
(16, '28/12/22' , 'E', '2', '0', '1'),
(17, '24/12/22' , 'E', '3', '0', '1'),
(18, '14/07/07' , '1', '0', '0', '1'),
(19, '22/12/22' , '2', '1', '0', '1');
I tried this through the online Fiddle pages, but it throws up errors, so either I'm doing it incorrectly, or it's because there was no option for Firebird. Hopefully irrelevant, as I have the table already through the front-end.
One of my earlier queries which works as expected is shown below, along with its output:
SELECT
"Vehicle Type",
DATEDIFF(DAY, "Date", CURRENT_DATE) AS "Days Since 3rd Last Event"
FROM
(
SELECT
"Date",
"Events",
"Vehicle Type",
"Event Count",
ROW_NUMBER() OVER (PARTITION BY "Vehicle Type" ORDER BY "Date" DESC) AS "rn"
FROM
(
SELECT
"Date",
"Events",
"Vehicle Type",
SUM("Events") OVER (PARTITION BY "Vehicle Type" ORDER BY "Date" DESC) AS "Event Count"
FROM "Data Entry"
)
WHERE "Event Count" >= 3
)
WHERE "rn" = 1
Vehicle Type
Days Since 3rd Last Event
A
3
B1
191
B2
1
C
3
D1
347
D2
343
D3
1252
D4
14
E
8
In this output, it does not list every vehicle because not all vehicles have an Event Count that is equal to or greater than 3. The new query I am trying to put together is a combination of different queries (omitted to keep things relevant, plus they already work on their own), with a rewrite of the above code as well:
SELECT
"Vehicle Type",
SUM("Hours 1" + "Hours 2") AS "Total Hours",
MAX(CASE
WHEN
"Total Events" = 3
THEN
DATEDIFF(DAY, "Date", CURRENT_DATE)
END
) "Days Since 3rd Last Event"
FROM
(
SELECT
"Vehicle Type",
"Date",
"Hours 1",
"Hours 2",
CASE
WHEN
"Events" > 0
THEN
SUM( "Events")
OVER(
PARTITION BY "Vehicle Type"
ORDER BY "Date" DESC
)
END
"Total Events"
FROM
"Data Entry"
)
GROUP BY "Vehicle Type"
ORDER BY "Vehicle Type"
The expected output should be:
Vehicle Type
Days Since 3rd Last Event
Total Hours
1
1
2
1
A
3
3
B1
191
3
B2
1
1
C
3
2
D1
347
1
D2
343
2
D3
1252
1
D4
14
4
E
8
2
However, the actual output is:
Vehicle Type
Days Since 3rd Last Event
Total Hours
1
1
2
1
A
3
B1
191
3
B2
1
C
3
2
D1
1
D2
2
D3
1
D4
14
4
E
2
Granted, I've mixed and matched code, made some up myself, and copied some parts from elsewhere online, so there's a good chance I've not understood something correctly and blindly added it in thinking it would work, but now I'm at a loss as to what that could be. I've had a play around with changing the values of the WHEN statements and altering the operators between =, >, and >=, but any deviation from what's currently shown above outputs incorrect numbers. At least the three numbers displayed in the actual output are correct.
You could try using two rankings:
the first one that catches last three rows
the second one that catches your last row among the possible three
then get your date differences.
WITH last_three AS (
SELECT "Vehicle Type", "Date",
SUM("Hours 1"+"Hours 2") OVER(PARTITION BY "Vehicle Type") AS "Total Hours",
ROW_NUMBER() OVER(PARTITION BY "Vehicle Type" ORDER BY "Date" DESC) AS rn
FROM "Data Entry"
), last_third AS (
SELECT "Vehicle Type", "Date", "Total Hours",
ROW_NUMBER() OVER(PARTITION BY "Vehicle Type" ORDER BY rn DESC) AS rn2
FROM last_three
WHERE rn <= 3
)
SELECT "Vehicle Type",
DATEDIFF(DAY, "Date", CURRENT_DATE) AS "Days Since 3rd Last Event",
"Total Hours"
FROM last_third
WHERE rn2 = 1
ORDER BY "Vehicle Type"
Check the demo here.
Note: You will get values for the "Vehicle Type" 1 and 2 too. If you can explain the rationale behind having those values empty, this query can be tweaked accordingly.

Run rate calculate in pgsql

I Have this table:
CREATE TABLE data
(
Event_Date date,
approved int,
rejected int
)
INSERT INTO data (Event_date, approved, rejected)
VALUES
('20190910', '5', '2'),
('20190911', '6', '3'),
('20190912', '5', '2'),
('20190913', '7', '5'),
('20190914', '8', '4'),
('20190915', '10', '2'),
('20190916', '4', '1')
How to make a loop or something else for calculate run rate and get results(in Rolling monthly rate CL I write how formula need to be use) like this:
Event_date approved, rejected Rolling monthly rate
------------------------------------------------------------
20190901 5 2 ---
20190902 6 3 6+5/5+6+2+3
20190903 4 2 6+4/6+3+4+2
20190903 7 5 7+4/4+2+7+5
20190904 8 4 8+4/7+5+8+4
20190905 10 2 ....
20190906 4 1 .....
The lag() function, which returns the previous value, is perfect for this task.
You need to write a case when statement and skip the first entry since there is no previous value and then calculate using the desired formula.
select *, case when row_number() over() > 1
then approved + lag(approved) over() / approved + rejected + lag(approved) over() + lag(rejected) over()
end as rate
from my_table
Demo in DBfiddle

SQL find overlapping appointments

I am trying to make a report that will determine if any clients (patient_id) have a duplicate appointment in our system. I have the fields of proc_chron (start time down to the second), proc_chron_end (end time down to the second), and proc_duration. Thank you in advance for any help.
select
patient_id,
attending_id,
proc_duration,
proc_chron,
proc_chron_end
from patient_clin_tran
where place_of_service not in ('23', '24', '25', '26')
and (proc_chron between '2015-06-01' and '2015-09-01')
and billing_proc_code not in ('BHHMTH')
On way would be to add a exists predicate with a correlated subquery in the where clause that limits the result to those appointments that overlap.
select
patient_id,
attending_id,
proc_duration,
proc_chron,
proc_chron_end
from patient_clin_tran p -- notice the table alias
where place_of_service not in ('23', '24', '25', '26')
and (proc_chron between '2015-06-01' and '2015-09-01')
and billing_proc_code not in ('BHHMTH')
and case when exists (
select 1 from patient_clin_tran
where patient_id = p.patient_id
and attending_id <> p.attending_id
and p.proc_chron < proc_chron_end
and p.proc_chron_end > proc_chron
) then 1 else 0 end = 1
order by p.patient_id, p.attending_id;
Sample SQL Fiddle with some imaginary data.
This only checks for overlapping appointments with different attending_id. If you want to check for overlaps with the same attending then you would have to remove the and attending_id <> p.attending_id and instead add a condition that uniquely identifies each row so that appointments don't overlap with themselves.
This would tell you where you have over lapping appointments:
;WITH cte AS (
SELECT
patient_id
,attending_id
,proc_duration
,proc_chron
,proc_chron_end
FROM patient_clin_tran
WHERE place_of_service NOT IN ('23', '24', '25', '26')
AND proc_chron BETWEEN '2015-06-01' AND '2015-09-01'
AND billing_proc_code NOT IN ('BHHMTH'))
SELECT c1.*
FROM cte c1
INNER JOIN cte c2 ON c1.patient_id = c2.patient_id
WHERE c2.proc_chron BETWEEN c1.proc_chron AND c1.proc_chron_end
AND c2.proc_chron_end BETWEEN c1.proc_chron AND c1.proc_chron_end
AND c1.attending_id != c2.attending_id
All I did was wrap your query in a common table expression and the join it with itself on the patient ID. The where clause then filters only appoints that overlap excluding the identical appointment.

Deleting rows in a single database table based on the values of other rows

I have a fairly complex requirement I would like to solve using SQL in a Postgres DB. I'm sure this would be addressed in any order management system however I cannot find anything of a similar nature.
I have the following table (and values):
CREATE TABLE TABLE1 (
ID varchar(8),
ORIG_ID varchar(8),
STATUS varchar(8),
VALIDITY varchar(8)
);
INSERT INTO TABLE1
(ID, ORIG_ID, STATUS, VALIDITY)
VALUES
('1', '1', 'REPLACED','DAY'),
('2', '1', 'REPLACED','DAY'),
('3', '1', 'FILLED','DAY'),
('4', '4', 'REJECTED','DAY'),
('5', '5', 'PARTIAL','GTC'),
('6', '6', 'EXPIRED','GTD'),
('7', '7', 'REPLACED','GTD'),
('8', '7', 'PARTIAL','GTD'),
('9', '9', 'FILLED', 'GTD'),
('10', '10', 'NEW', 'DAY'),
('11', '11', 'NEW', 'GTD'),
('12', '12', 'DFD', 'GTD'),
('13', '13', 'REPLACED', 'GTD'),
('14', '13', 'FILLED', 'GTD')
;
N.B -
Please ignore the data types on the fields
The final table may have thousands of entries to process
The above can be pasted directly into SQL Fiddle if required (PostgreSQL 9.3.1)
The requirements I have are:
Delete all entries that have a STATUS of either:
FILLED, EXPIRED, REJECTED, CANCELLED
PARTIAL/NEW - If the VALIDITY is not GTD/GTC (i.e. only DAY)
REPLACED - Unless there are other entries with the same ORIG_ID in a PARTIAL/NEW STATUS and not GTD/GTC (still working orders)
TBD - To Be Deleted:
TBD ('1', '1', 'REPLACED','DAY'),
TBD ('2', '1', 'REPLACED','DAY'),
TBD ('3', '1', 'FILLED','DAY'),
TBD ('4', '4', 'REJECTED','DAY'),
('5', '5', 'PARTIAL','GTC'),
TBD ('6', '6', 'EXPIRED','GTD'),
('7', '7', 'REPLACED','GTD'),
('8', '7', 'PARTIAL','GTD'),
TBD ('9', '9', 'FILLED', 'GTD'),
TBD ('10', '10', 'NEW', 'DAY'),
('11', '11', 'NEW', 'GTD'),
('12', '12', 'DFD', 'GTD'),
TBD ('13', '13', 'REPLACED', 'GTD'),
TBD ('14', '13', 'FILLED', 'GTD')
I've tried looking and the closet I could find was the following:
Delete with join on the same table and limit clause
However I couldn't get it to work while incorporating the requirements above.
As this will be run at the end of day I have had a few thoughts in such as changing all entries with VALIDITY of DAY, setting STATUS to EXPIRED. Then just deleting them all but then still hit the issue of STATUS with the GTD/GTC orders. I'm unsure if this would also be faster than handling it all under the same logic.
Any help (or new ideas) would be appreciated on how to tackle this issue.
Delete from table1
WHERE status in ('FILLED','EXPIRED','REJECTED','CANCELLED')
OR (status in ('PARTIAL','NEW') AND validity not in ('GTD','GTC'))
OR (status = 'REPLACED' and orig_ID not in
(select ORig_ID from table1 where status in ('PARTIAL','NEW')));
http://sqlfiddle.com/#!15/9e465/28/0
what is your PostgreSQL version ?
anyways here is what I come up with
delete from TABLE1 where
STATUS in ('FILLED','EXPIRED','REJECTED','CANCELLED') or
STATUS in (select STATUS from TABLE1 where STATUS in ('PARTIAL','NEW')
and VALIDITY!='DAY') OR
STATUS in (select status from TABLE1 where STATUS ='REPLACED'
and orig_ID not in
(select ORig_ID from table1 where status in ('PARTIAL','NEW')))
http://sqlfiddle.com/#!15/9e465/54
Try with this DELETE sentence:
DELETE FROM TABLE1 as MASTER
WHERE
STATUS IN ('FILLED', 'EXPIRED', 'REJECTED', 'CANCELLED') OR
(STATUS IN ('PARTIAL','NEW') AND VALIDITY NOT IN ('GTD','GTC')) OR
(STATUS='REPLACED' AND ID NOT IN
(SELECT ORIG_ID FROM TABLE1 OTHER
WHERE OTHER.ORIG_ID=MASTER.ID AND
STATUS IN ('PARTIAL','NEW') AND VALIDITY IN ('GTD','GTC')));
SQL Fiddle Example (With SELECT sentence)
Unless I'm mistaken, there's either an error in the output in the OP, or the logic.
DELETE
FROM TABLE1 AS T
WHERE STATUS IN ('FILLED', 'EXPIRED', 'REJECTED', 'CANCELLED')
OR ( STATUS IN ('PARTIAL', 'NEW')
AND VALIDITY NOT IN ('GTD', 'GTC') )
OR ( STATUS = 'REPLACED'
AND NOT EXISTS
(SELECT 1
FROM TABLE1 tbl1
WHERE T.ID <> tbl1.ID
AND T.ORIG_ID = tbl1.ORIG_ID
AND tbl1.STATUS IN ('PARTIAL', 'NEW')
AND tbl1.VALIDITY NOT IN ('GTD', 'GTC')
)
);
http://sqlfiddle.com/#!15/9e465/16
EDIT: It seems OP means
"REPLACED - Unless [it does not have GTD/GTC status ] and there are other entries with the same ORIG_ID"
rather than
"REPLACED - Unless there are other entries with the same ORIG_ID [that do not have a GTD/GTC status]"

Multiple columns are specified in an aggregated expression containing an outer reference TSQL

I have the following query:
SELECT
FileNumber,
dbo.GetLocalDateTimeFunc(SentDate) AS SentDate
INTO #tmp1
FROM FileMain f
JOIN FileActions fa ON f.FileID = fa.FileID
WHERE ActionDefID = 15 AND SentDate IS NOT NULL
SELECT
FileNumber,
dbo.GetLocalDateTimeFunc(ReceivedDate) AS ReceivedDate
INTO #tmp2
FROM FileMain f
JOIN FileActions fa ON f.FileID = fa.FileID
WHERE ActionDefID = 23 AND ReceivedDate IS NOT NULL
SELECT DISTINCT
o.Name AS Company, fm.FileNumber, pc.Name as Client,
p.State, c.County, t1.SentDate, t2.ReceivedDate,
(SELECT sum(case
when dateadd(day, datediff(day, 0, t1.SentDate), 0) = dateadd(day, datediff(day, 0, t2.ReceivedDate), 0) then
datediff(second, t1.SentDate, t2.ReceivedDate)
when [DATE] = dateadd(day, datediff(day, 0, t1.SentDate), 0) then
case
when t1.SentDate > [DATE] + begin_time then datediff(second, t1.SentDate, [DATE] + end_time)
else duration
end
when [DATE] = dateadd(day, datediff(day, 0, t2.ReceivedDate), 0) then
case
when t2.ReceivedDate < [DATE] + end_time then datediff(second, [DATE] + begin_time, t2.ReceivedDate)
else duration
end
else duration
end
)
/ 60.0 / 60.0
FROM F_TABLE_DATE(t1.SentDate, t2.ReceivedDate) d
INNER JOIN Unisource_Calendar c ON d.WEEKDAY_NAME_LONG = c.day_name)
FROM Office o
JOIN PartnerCompany pc ON o.OfficeID = pc.OfficeID
JOIN FileMain fm ON o.OfficeID = fm.OfficeID AND pc.PartnerCompanyID = fm.ClientID
JOIN Property p ON p.FileID = fm.FileID
JOIN County c ON p.CountyID = c.CountyID
JOIN FileActions fa ON fm.FileID = fa.FileID
JOIN #tmp1 t1 ON t1.FileNumber = fm.FileNumber
JOIN #tmp2 t2 ON t2.FileNumber = fm.FileNumber
WHERE p.State IN ('AR', 'CA', 'CO', 'DE', 'DC', 'FL', 'GA', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NJ', 'NV', 'NH', 'NY', 'NC', 'ND', 'OH', 'OK', 'PA', 'RI', 'SC', 'TN', 'TX', 'VA', 'WV', 'WI')
ORDER BY SentDate, FileNumber DESC
I'm getting the following error on my subquery:
Multiple columns are specified in an aggregated expression containing an outer reference. If an expression being aggregated contains an outer reference, then that outer reference must be the only column referenced in the expression.
Does anybody know how to fix this?
Or if someone has a function that can calculate datetime differences while excluding business hours and weekends that would help also. Thanks!
I would recommend you to simplify your code using CTEs for a start (enumeration of ALL tables distracts to give a precise statement). Also you should try your aggregate SUM function as a part of PARTITION by expression. This would probably help to avoid the problem you mentioned.
From what I can glean, the table function F_Table_Date is returning DATE or DATETIME rows for each day between the two parameters, and the UnisourceCalendar Is likely a list of work days (to allot for holidays as you mentioned). If this is the case, and UnisourceCalendar also returns a DATE or DATETIME column, consider this for your subquery:
SELECT (COUNT(*) * 60*60*24)
+ (
SELECT COUNT(*)
FROM UnisourceCalendar
WHERE [DATE] = CAST(CONVERT(VARCHAR,t1.SentDate+1,112) AS DATETIME)
)*DATEDIFF(SS,t1.SentDate,CAST(CONVERT(VARCHAR,t1.SentDate+1,112) AS DATETIME))
+ (
SELECT COUNT(*)
FROM UnisourceCalendar
WHERE [DATE] = CAST(CONVERT(VARCHAR,t1.SentDate+1,112) AS DATETIME)
)*DATEDIFF(SS,CAST(CONVERT(VARCHAR,t2.ReceivedDate,112) AS DATETIME),t2.ReceivedDate)
FROM UnisourceCalendar C
WHERE C.[DATE] > t1.SentDate AND C.[DATE] < t2.ReceivedDate
GROUP BY t1.SentDate, t2.ReceivedDate
What's at Play here:
Presuming 1 row per business day from UnisourceCalendar, any other join is superfluous.
A count is all that's needed, then.
The datediff of a converted/cast value of one date against itself using style 112 strips the time out and is recast as midnight, thus allowing us to get the seconds to next midnight from the sent date, and from the previous midnight of the received date, but only if each date is in the unisource calendar (mulitply by count, if 0, then no seconds added, if 1, then add the extra seconds).
Output is presuming that you will be dividing the results down to hours outside the subquery as you are.
Complicated? Sure, but it should output the results you're looking for in relatively short order.