Grouping data by columns - sql

I have a data set like this:
id_tecnico dia hora total
<chr> <dbl> <int> <int>
1 0011ab4f-6871-40f4-91f2-818e309baa41 8 13 1
2 0011ab4f-6871-40f4-91f2-818e309baa41 45 10 1
3 0011ab4f-6871-40f4-91f2-818e309baa41 46 9 1
4 0011ab4f-6871-40f4-91f2-818e309baa41 50 14 1
5 0011ab4f-6871-40f4-91f2-818e309baa41 58 12 1
6 0011ab4f-6871-40f4-91f2-818e309baa41 70 12 1
7 0011ab4f-6871-40f4-91f2-818e309baa41 81 11 1
8 0011ab4f-6871-40f4-91f2-818e309baa41 86 11 1
9 0011ab4f-6871-40f4-91f2-818e309baa41 89 9 1
10 0011ab4f-6871-40f4-91f2-818e309baa41 92 11 1
I would like to group the data the column total by hour, but I would like the result by column, not by row, creating a new column for each hour sum : hour1, hour2, hour3...
Can someone help me?

Related

How to get previous SKU's Amount? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 12 days ago.
Improve this question
Is there a way I can get previous SKU data in present row in SQL Server:
Date
Fol
SKU
Amount
01-01-2021
44
1
2
01-01-2021
44
2
3
05-03-2021
45
1
4
05-03-2021
45
2
5
08-06-2021
46
1
6
08-06-2021
46
2
7
13-08-2021
47
1
8
13-08-2021
47
2
9
Expected
Date
Fol
SKU
Amount
Previous Amount
01-01-2021
44
1
2
---------
05-03-2021
45
1
4
2
08-06-2021
46
1
6
4
13-08-2021
47
1
8
6
01-01-2021
44
2
3
---
05-03-2021
45
2
5
3
08-06-2021
46
2
7
5
13-08-2021
47
2
9
7
I've tried lag function but it's not resulting as expected
Date
Fol
SKU
Amount
Previous Amount
01-01-2021
44
1
2
---------
01-01-2021
44
2
3
2
05-03-2021
45
1
4
3
05-03-2021
45
2
5
4
08-06-2021
46
1
6
5
08-06-2021
46
2
7
6
13-08-2021
47
1
8
7
13-08-2021
47
2
9
8
Thanks!
The window functions are well worth your time to get comfortable with them
Select *
,PrevAmt = lag(AMOUNT,1) over (partition by SKU order by date)
From YourTable
Results

Need to Roll Parent Quantities to Calculate Total Quantity

Thanks in advance for any assistance you can provide. I have spent hours on this with no luck.
I'm working with an indented bill of material table which has an end part id, a sequence number, a level and a quantity. The goal is to determine the total cumulative quantity of each row on this table.
What makes this difficult is that to determine the total quantity, the child quantity needs to be multiplied by it's parent quantity. The parent quantity of that parent needs to be multiplied by it's parent quantity and so on.
For example, a level 3 part has a component quantity of 5. It's parent the level 2 part has a component quantity of 2. It's parent the level 1 part has a component quantity of 3. This means the level 3 part total quantity is 30 (3 X 2 X 5).
With the assistance of SO (specifically #KKK) the parent quantity was able to be calculated in the below query. After this was resolved I realized I now need two additional columns, one that shows the Rolled/Cumulative quantities of the parent rows and one that shows the total quantity of the child.
The attached screenshot has the two columns that need to be added highlighted in yellow. Here is the current SQL (using Oracle 10.2) for the columns that are not in yellow:
select
end_part_id, sort_seq_no, indented_lvl, comp_qty,
(select distinct first_value(a.comp_qty) over (order by a.sort_seq_no desc, TRIM(a.indented_lvl) desc)
from
report_table a
where
a.end_part_id = b.end_part_id
and a.sort_seq_no < b.sort_seq_no
and TRIM(a.indented_lvl) < TRIM(b.indented_lvl)) as "PARENT_QTY"
from report_table b
Expected Results
END_PART_ID SORT_SEQ_NO INDENTED_LVL COMP_QTY PARENT_QTY ROLLED_PARENT QTY TOTAL_QTY
PARTX 1 1 2 1 1 2
PARTX 2 2 5 2 2 10
PARTX 3 3 2 5 10 20
PARTX 4 4 1 2 20 20
PARTX 5 5 1 1 20 20
PARTX 6 6 1 1 20 20
PARTX 7 5 4 1 20 80
PARTX 8 6 1 4 80 80
PARTX 9 2 7 2 2 14
PARTX 10 3 2 7 14 28
PARTX 11 3 2 7 14 28
PARTX 12 4 1 2 28 28
PARTX 13 4 1 2 28 28
PARTX 14 3 8 7 14 112
PARTX 15 1 1 1 1 1
PARTX 16 2 7 1 1 7
PARTX 17 3 2 7 7 14
PARTX 18 3 2 7 7 14
PARTX 19 4 1 2 14 14
PARTX 20 4 1 2 14 14

Oracle - Group By Creating Duplicate Rows

I have a query that looks like this:
select nvl(trim(a.code), 'Blanks') as Ward, count(b.apcasekey) as UNSP, count(c.apcasekey) as GRAPH,
count(d.apcasekey) as "ANI/PIG",
(count(b.apcasekey) + count(c.apcasekey) + count(d.apcasekey)) as "TOTAL ACTIVE",
count(a.apcasekey) as "TOTAL OPEN" from (etc...)
group by a.code
order by Ward
The reason I have nvl(trim(a.code), 'Blanks') as Ward is that sometimes a.code is a blank string, sometimes it's a null.
The problem is that when I use the Group By statement, I can't use Ward or I get the error
Ward: Invalid Identifier
I can only use a.code so I get 2 rows for 'Blanks', as per below
1 Blanks 7 0 0 7 7
2 Blanks 23 1 1 25 30
3 W01 75 4 0 79 91
4 W02 62 1 0 63 72
5 W03 140 2 0 142 162
6 W04 6 1 0 7 7
7 W05 46 0 1 47 48
8 W06 322 46 1 369 425
9 W07 91 0 1 92 108
10 W08 93 2 0 95 104
11 W09 28 1 0 29 30
12 W10 25 0 0 25 28
What I need, is for the row with 'Blanks' to combined into 1 row. Little help?
Thanks.
You can not use the alias in the GROUP BY, but you can use the expression that builds the value:
GROUP BY nvl(trim(a.code), 'Blanks')

Getting average of product sales each day and calculate number of days that have positive sales

I have this table TARGETSALE that have the following columns
SELECT DATE, WEEK, BRANCH, PROD, TARGETREACH
FROM TARGETSALE
WHERE BRANCH = 1
AND WEEK BETWEEN 52 AND 53;
DATE WEEK BRANCH PROD TARGETREACH
-------------------------------------------------------------------
01/09/2014 52 1 1 50
02/09/2014 52 1 1 -10
03/09/2014 52 1 1 50
04/09/2014 52 1 1 50
05/09/2014 52 1 1 40
06/09/2014 52 1 1 -10
07/09/2014 53 1 1 -5
08/09/2014 53 1 1 0
09/09/2014 53 1 1 10
10/09/2014 53 1 1 20
11/09/2014 53 1 1 30
12/09/2014 53 1 1 40
13/09/2014 53 1 1 0
01/09/2014 52 1 2 20
02/09/2014 52 1 2 0
03/09/2014 52 1 2 0
04/09/2014 52 1 2 10
05/09/2014 52 1 2 20
06/09/2014 52 1 2 10
07/09/2014 53 1 2 -10
08/09/2014 53 1 2 10
09/09/2014 53 1 2 -10
10/09/2014 53 1 2 20
11/09/2014 53 1 2 20
12/09/2014 53 1 2 40
13/09/2014 53 1 2 0
01/09/2014 52 1 3 30
02/09/2014 52 1 3 30
03/09/2014 52 1 3 5
04/09/2014 52 1 3 0
05/09/2014 52 1 3 10
06/09/2014 52 1 3 -10
07/09/2014 53 1 3 -10
08/09/2014 53 1 3 -10
09/09/2014 53 1 3 20
10/09/2014 53 1 3 10
11/09/2014 53 1 3 40
12/09/2014 53 1 3 10
13/09/2014 53 1 3 10
"targetsales" shows how much over the target the sales is, where negative means how far below the target the sales was. How can I do the following:
1. I need to get the average for all the product for each day. Something like this:
DATE BRANCH AVERAGE_SALES_OF_ALL_PRODUCT
01/09/2014 1 33.33
02/09/2014 1 -1.67
...and so on
And then I need to have another query that shows how many days within those two weeks that there's positive average sales. Something like this:
BRANCH 2WEEKS_SINCE DAYS_WITH_POSITIVE_AVERAGE_SALES
1 53 9
Above just an example not a real result.
Sorry, hope this not too confusing. Thank you so much.
In Oracle, the date type might still have a time component. If you do not know if this is there, then use trunc() to remove it:
select trunc(date), branch, avg(targetreach)
from targetsale
group by truncdate, branch
order by 1, 2;
For the second query, you want to use case:
select branch, count(distinct case when targetreach > 0 then date end) as DaysWithPositiveSales
from targetsales
group by branch;
If you know there is one row per date per branch -- and the time component of the date is empty -- then the distinct is not necessary.
1)
SELECT TRUNC(DATE, 'DD'), BRANCH, SUM(TARGETREACH)
FROM TARGETSALE WHERE BRANCH = 1 AND WEEK BETWEEN 52 AND 53
GROUP BY TRUNC(DATE, 'DD'), BRANCH;
2)
SELECT BRANCH, SUM(DECODE(ABS(TARGETREACH), 1, 1, 0)
FROM TARGETSALE WHERE BRANCH = 1 AND WEEK BETWEEN 52 AND 53
GROUP BY BRANCH;

Moving sum over date range

I have this table that has wide range of dates and a corresponding value for each one of those dates, an example shown below.
Date Value
6/01/2013 8
6/02/2013 4
6/03/2013 1
6/04/2013 7
6/05/2013 1
6/06/2013 1
6/07/2013 3
6/08/2013 8
6/09/2013 4
6/10/2013 2
6/11/2013 10
6/12/2013 4
6/13/2013 7
6/14/2013 3
6/15/2013 2
6/16/2013 1
6/17/2013 7
6/18/2013 5
6/19/2013 1
6/20/2013 4
What I am trying to do is create a query that will create a new column that will display the sum of the Value’s column for a specified date range. For example down below, the sum column contains the sum of its corresponding date going back one full week. So the Sum of the date 6/9/2013 would be the sum of the values from 6/03/2013 to 6/09/2013.
Date Sum
6/01/2013 8
6/02/2013 12
6/03/2013 13
6/04/2013 20
6/05/2013 21
6/06/2013 22
6/07/2013 25
6/08/2013 25
6/09/2013 25
6/10/2013 26
6/11/2013 29
6/12/2013 32
6/13/2013 38
6/14/2013 38
6/15/2013 32
6/16/2013 29
6/17/2013 34
6/18/2013 29
6/19/2013 26
6/20/2013 23
I’ve tried to using the LIMIT clause but I could not get it to work, any help would be greatly appreciated.
zoo has a function rollapply which can do what you need:
z <- zoo(x$Value, order.by=x$Date)
rollapply(z, width = 7, FUN = sum, partial = TRUE, align = "right")
## 2013-06-01 8
## 2013-06-02 12
## 2013-06-03 13
## 2013-06-04 20
## 2013-06-05 21
## 2013-06-06 22
## 2013-06-07 25
## 2013-06-08 25
## 2013-06-09 25
## 2013-06-10 26
## 2013-06-11 29
## 2013-06-12 32
## 2013-06-13 38
## 2013-06-14 38
## 2013-06-15 32
## 2013-06-16 29
## 2013-06-17 34
## 2013-06-18 29
## 2013-06-19 26
## 2013-06-20 23
Using data.table
require(data.table)
#Build some sample data
data <- data.table(Date=1:20,Value=rpois(20,10))
#Build reference table
Ref <- data[,list(Compare_Value=list(I(Value)),Compare_Date=list(I(Date)))]
#Use lapply to get last seven days of value by id
data[,Roll.Val := lapply(Date, function(x) {
d <- as.numeric(Ref$Compare_Date[[1]] - x)
sum((d <= 0 & d >= -7)*Ref$Compare_Value[[1]])})]
head(data,10)
Date Value Roll.Val
1: 1 14 14
2: 2 7 21
3: 3 9 30
4: 4 5 35
5: 5 10 45
6: 6 10 55
7: 7 15 70
8: 8 14 84
9: 9 8 78
10: 10 12 83
Here is another solution if anyone is interested:
library("devtools")
install_github("boRingTrees","mgahan")
require(boRingTrees)
rollingByCalcs(data,dates="Date",target="Value",stat=sum,lower=0,upper=7)
Here is one way of doing it
> input <- read.table(text = "Date Value
+ 6/01/2013 8
+ 6/02/2013 4
+ 6/03/2013 1
+ 6/04/2013 7
+ 6/05/2013 1
+ 6/06/2013 1
+ 6/07/2013 3
+ 6/08/2013 8
+ 6/09/2013 4
+ 6/10/2013 2
+ 6/11/2013 10
+ 6/12/2013 4
+ 6/13/2013 7
+ 6/14/2013 3
+ 6/15/2013 2
+ 6/16/2013 1
+ 6/17/2013 7
+ 6/18/2013 5
+ 6/19/2013 1
+ 6/20/2013 4 ", as.is = TRUE, header = TRUE)
> input$Date <- as.Date(input$Date, format = "%m/%d/%Y") # convert Date
>
> # create a sequence that goes a week back from the current data
> x <- data.frame(Date = seq(min(input$Date) - 6, max(input$Date), by = '1 day'))
>
> # merge
> merged <- merge(input, x, all = TRUE)
>
> # replace NAs with zero
> merged$Value[is.na(merged$Value)] <- 0L
>
> # use 'filter' for the running sum and delete first 6
> input$Sum <- filter(merged$Value, rep(1, 7), sides = 1)[-(1:6)]
> input
Date Value Sum
1 2013-06-01 8 8
2 2013-06-02 4 12
3 2013-06-03 1 13
4 2013-06-04 7 20
5 2013-06-05 1 21
6 2013-06-06 1 22
7 2013-06-07 3 25
8 2013-06-08 8 25
9 2013-06-09 4 25
10 2013-06-10 2 26
11 2013-06-11 10 29
12 2013-06-12 4 32
13 2013-06-13 7 38
14 2013-06-14 3 38
15 2013-06-15 2 32
16 2013-06-16 1 29
17 2013-06-17 7 34
18 2013-06-18 5 29
19 2013-06-19 1 26
20 2013-06-20 4 23
>