Cognos Report total values with same date - sql

I'm building a report in IBM Cognos report studio.
A set of data looks like this:
including location name, item name , item number , and days in inventory.
id date type hours
1 10/27/2021 work 7
1 10/27/2021 overtime 1
1 10/24/2021 work 7
1 10/26/2021 work 7
I use total to sum the hours for the same date
total ([Hours] for [Date],[ID])
It returns:
id date type hours
1 10/27/2021 work 8
1 10/27/2021 overtime 8
1 10/24/2021 work 7
1 10/26/2021 work 7
Then I tried a count and running count. then set count = 1 in the filter. Set object aggregate after.
Data returns:
id date type hours count
1 10/27/2021 work 1 1
1 10/27/2021 overtime 1 2
1 10/24/2021 work 1 1
1 10/26/2021 work 1 1
what I need:
id date type hours
1 10/27/2021 work 8
1 10/24/2021 work 7
1 10/26/2021 work 7
Thanks for your help!

The requirement is still a bit unclear, but if I understand it correctly, the query needs these data items:
Name
Expression
Aggregation
id
[id]
none
date
[date]
none
type
'work'
none
hours
[hours]
Total
Then add a filter with this expression:
[type] in ('work', 'overtime')
Include any values for [type] that you consider "work".
Alternatively, because your comments indicate your sample input and desired output are incomplete...
Name
Expression
Aggregation
id
[id]
none
date
[date]
none
type
case when [type] in ('work', 'overtime') then 'work' else [type] end
none
hours
[hours]
Total
...without the filter.

Related

Get earliest value from a column with other aggregated columns in postgresql

I have a very simple stock ledger dataset.
1. date_and_time store_id product_id batch opening_qty closing_qty inward_qty outward_qty
2. 01-10-2021 14:20:00 56 a 1 5 1 0 4
3. 01-10-2021 04:20:00 56 a 1 8 5 0 3
4. 02-10-2021 15:30:00 56 a 1 9 2 1 8
5. 03-10-2021 08:40:00 56 a 2 2 6 4 0
6. 04-10-2021 06:50:00 56 a 2 8 4 0 4
Output I want:
select date, store_id,product_id, batch, first(opening_qty),last(closing_qty), sum(inward_qty),sum(outward_qty)
e.g.
1. date store_id product_id batch opening_qty closing_qty inward_qty outward_qty
2. 01-10-2021 56 a 1 8 1 0 7
I am writing a query using First_value window function and tried several others but not able to get the out put I want.
select
date,store_id,product_id,batch,
FIRST_VALUE(opening_total_qty)
OVER(
partition by date,store_id,product_id,batch
ORDER BY created_at
) as opening__qty,
sum(inward_qty) as inward_qty,sum(outward_qty) as outward_qty
from table
group by 1,2,3,4,opening_total_qty
Help please.
As your expected result is one row per group of rows with the same date, you need aggregates rather than window functions which provide as many rows as the ones filtered by the WHERE clause. You can try this :
SELECT date_trunc('day', date),store_id,product_id,batch
, (array_agg(opening_qty ORDER BY datetime ASC))[1] as opening__qty
, (array_agg(closing_qty ORDER BY datetime DESC))[1] as closing_qty
, sum(inward_qty) as inward_qty
, sum(outward_qty ) as outward_qty
FROM table
GROUP BY 1,2,3,4
see the test result in dbfidle.

SQL Server Date Diff On Rows In Table

I have a query that groups a start and stop time on different rows, where Batch Number 1 is the start, and BatchNumber 2 is the stop time, and I need to do a datediff on them. I have tried adding row numbers and trying to do something like date diff rows 1 and 2, 3 and 4, etc, with no luck.
So I have to do a date diff on 1 and 3, 2 and 4, and so on whenever there is batch 1 and 2 together.
Here is what my data looks like:
RowNumber OrderNumber IDCode DateVal MilestoneID BatchNumber
-------------------------------------------------------------------
1 5017555.1 4077213 2018-08-30 12:22:51.253 15 1
3 5017555.1 4081502 2018-09-05 12:41:08.817 16 2
2 5017555.1 4095474 2018-09-18 10:42:47.457 15 1
4 5017555.1 4095665 2018-09-18 12:07:11.083 16 2
LAG allows you to get value from a previous row:
Select *
datediff (day, LAG(DateVal) OVER (ORDER BY OrderNumber) ,DateVal )
From YourTable
You can also use Lead to get value from next row

SQL - Creating a Grouped 'range' set

I have a table of support tickets - with time opened and time closed. I would like to create a table of ranges, as such:
ticket count | time to close
----------------------------------
30 | up to 2 hours
25 | 2 - 4 hours
10 | 4 - 6 hours
what i have so far gives me the range (using a CASE with DATEDIFF), but i cant figure out how to group the eventual range.
When trying to GROUP on the new openTimeRange computed column, the error of course is that its an unknown column.
SELECT COUNT([tblTickets].*), DATEDIFF(hh,[dateOpened],[closeDate]) AS OpenTime
, case when DATEDIFF(hh,[dateOpened],[closeDate]) between 0 and 2 then '0-2'
when DATEDIFF(hh,[dateOpened],[closeDate]) between 3 and 4 then '3-4'
when DATEDIFF(hh,[dateOpened],[closeDate]) between 5 and 6 then '4-6'
end as openTimeRange
FROM [tblTickets]
WHERE closeDate is not null
GROUP BY [dateOpened],[closeDate]
Using MSSQL 2005 SP4
Thanks!
As you mentioned, if you try to GROUP BY the openTimeRange alias column in your original query, you will get an error. The reason for this is that the GROUP BY clause is evaluated before the alias is assigned to the result set, and hence you cannot use it. Using an inline view should do the trick:
SELECT T.TicketCount, T.OpenTime, T.openTimeRange
FROM
(
SELECT COUNT([tblTickets].*) AS TicketCount,
DATEDIFF(hh,[dateOpened],[closeDate]) AS OpenTime,
CASE WHEN DATEDIFF(hh,[dateOpened],[closeDate]) BETWEEN 0 AND 2 THEN '0-2'
WHEN DATEDIFF(hh,[dateOpened],[closeDate]) BETWEEN 3 AND 4 THEN '3-4'
WHEN DATEDIFF(hh,[dateOpened],[closeDate]) BETWEEN 5 AND 6 THEN '4-6'
END AS openTimeRange
FROM [tblTickets]
WHERE closeDate IS NOT NULL
GROUP BY [dateOpened],[closeDate]
) T
GROUP BY T.openTimeRange

Update table in specific rows based on conditions for multiple previous rows

My dataset consists of daily (actually business days, but it shouldn't matter for the answer) timeseries for different companies and I work with PostgreSQL. I have an indicator variable in my dataset taking values 1, -1 and most of the times 0. For better readability of the question I refer to days where the indicator variable is unequal to zero as indicator days.
So for all indicator days that are preceded by another indicator day for the same company in the previous three days, the indicator variable shall be updated to zero.
We can work with the following example dataset:
day company indicator
2012-01-04 A 0
2012-01-04 B 0
2012-01-05 A 0
2012-01-05 B -1
2012-01-06 A 0
2012-01-06 B 0
2012-01-09 A 0
2012-01-09 B 0
2012-01-10 A 0
2012-01-10 B 1
2012-01-11 A 1
2012-01-11 B 1
2012-01-12 A 0
2012-01-12 B 0
2012-01-13 A 1
2012-01-13 B 1
So the indicator values that have to be updated to zero are: on 2012-01-10 the entry for company B, on 2012-01-11 the entry for company B and on 2012-01-13 both entries, because all these are preceded by another indicator day for the same company within 3 business days.
I tried the following
UPDATE test SET indicator = 0
WHERE day IN (
SELECT day
FROM (
SELECT company, day,
COUNT(CASE WHEN indicator <> 0 THEN 1 END)
OVER (PARTITION BY company ORDER BY day
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) As cnt
FROM test
) alias
WHERE cnt >= 2)
The idea was to count the days where the indicator variable is unequal to zero for the current day and the 3 preceding days. If it counts more than 1, it updates the indicator value to zero. Unfortunately it is not able to distinguish between companies. So what it does in the example data, is on 2012-01-11 it updates also the entry for company A to zero, because on the day before there is an indicator day for B.
Maybe I would need someting like "partition by company" for the update, but it doesn't exist.
Do you have any ideas how to fix it, or how to solve my problem with another approach?
Postgresql allows you to use more than one column for the IN statement, so I think you can just change your query to:
UPDATE test SET indicator = 0
WHERE (day, company) IN (
SELECT day, company
FROM (
SELECT company, day,
COUNT(CASE WHEN indicator <> 0 THEN 1 END)
OVER (PARTITION BY company ORDER BY day
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) As cnt
FROM test
) alias
WHERE cnt >= 2)
To get the results you need.
Example on SQL Fiddle

Counting Items/Rows in DB as Columns Grouped by Another Column

What I want to do is basically:
select Type, (Count(*) where Date='')as 10/1, (Count(*) where Date='')as 10/2
from my table
group by Type
What I want it to look like is:
Type 10/1 10/2
1 5 7
2 3 1
3 6 9
4 1 3
5 9 8
However, when I try to run a full select within each count column, I end up getting
Type 10/1 10/2
1 12 15
2 12 15
3 12 15
4 12 15
5 12 15
Any suggestions are appreciated. I'm not sure if I will need to run a pivot or not, but I wouldn't think so. Additionally after I can run that for any specific day, I was thinking about trying to put the date into a variable and trying to run the whole thing for a date range, generating columns dynamically for each day its run. I would probably create a new question for that though.
Try this;
SELECT TYPE
,SUM(CASE WHEN MyDate = '' THEN 1 ELSE 0 END) AS [10/1]
,SUM(CASE WHEN MyDate = '' THEN 1 ELSE 0 END) AS [10/2]
FROM MyTable
GROUP BY TYPE