How to bring corresponding data in the column - sql

How to bring the corresponding data in new columns by comparing there other attributes. here in the below table we have 2 weeks of data along with Store ID and Price type, if the price type is "Regular" then we have to add "Reduced" price with same criteria (Year, Week, StoreID) in the new column and if the price type is "Reduced" then we have to add "Regular" price with same criteria (Year, Week, StoreID) in the new column.
Year
Week
StoreID
PriceType
Price
2021
10
S
Regular
200
2021
10
S
Reduced
150
2021
10
D
Regular
180
2021
10
D
Reduced
120
2021
9
S
Regular
35
2021
9
D
Reduced
40
Has to be change like the below table, in the below output table, "Reduced/Regular" value is 150 in row number 1 because 150 is the corresponding value for 200 with criteria (2021, 10, S) and in 2nd row the Reduced/Regular value is 200 because 200 is the corresponding vale for 150 with criteria (2021, 10, S).
But last 2 rows for week 9 will gives 0 because we don't have corresponding criteria.
Year
Week
StoreID
PriceType
Price
Reduced/Regular
2021
10
S
Regular
200
150
2021
10
S
Reduced
150
200
2021
10
D
Regular
180
120
2021
10
D
Reduced
120
180
2021
9
S
Regular
35
0
2021
9
D
Reduced
40
0
Kindly help with this logic Thanks in advance

You can use window functions and conditional logic:
select t.*,
(case when priceType = 'Regular'
then max(case when priceType = 'Reduced' then price end) over (partition by year, week, storeId)
else max(case when priceType = 'Regular' then price end) over (partition by year, week, storeId)
end) as other_price
from t;
Happily, this is standard SQL and will work in any database.

Related

rolling sum to calculate YTD for each month group by product and save to separate columns using SQL

I have a data like this:
Order_No Product Month Qty
3001 r33 1 8
3002 r34 1 11
3003 r33 1 17
3004 r33 2 3
3005 r34 2 11
3006 r34 3 1
3007 r33 3 -10
3008 r33 3 18
I'd like to calculate total YTD qty for product and each month and save to separate columns. Below is what I want
Product Qty_sum_jan Qty_sum_feb Qty_sum_mar
r33 25 28 36
r34 11 22 23
I know how to use window function to calculate rolling sums but I have no idea to group them to separate columns. I currently use something like this:
case when Month = 1 then sum(Qty) over(partition by Product order by Month) else 0 end as Qty_sum_jan,
case when Month <=2 then sum(Qty) over(partition by Product order by Month) else 0 end as Qty_sum_feb,
case when Month <=3 then sum(Qty) over(partition by Product order by Month) else 0 end as Qty_sum_mar,
This will get me rolling sum by order but how to get to product level like what I show above? If I use group by then it will throw an error since Month is not in group by clause. I also cannot just use max to get the last value since qty can be negative so the last value may not be maximum. I use sparkSQL by the way
To my understanding, there is no need to use window functions. The following query achieves your desired output:
select
product,
sum(case when month = 1 then qty else 0 end) as sum_qty_jan,
sum(case when month <= 2 then qty else 0 end) as sum_qty_feb,
sum(case when month <= 3 then qty else 0 end) as sum_qty_mar
from your_table
group by 1;
Output:
product
sum_qty_jan
sum_qty_feb
sum_qty_mar
r33
25
28
36
r34
11
22
23

Count total without duplicate records

I have a table that contains the following columns: TrackingStatus, Year, Month, Order, Notes
I need to calculate the total number of tracking status for each year and month.
For example, if the table contains the following orders:
TrackingStatus
Year
Month
Order
Notes
F
2020
1
33
F
2020
1
33
DFF
E
2020
2
36
xxx
A
2021
3
34
X1
A
2021
3
34
DD
A
2021
3
88
A
2021
2
45
The result should be:
• Tracking F , year 2020, month 1 the total will be one (because it's the same year, month, and order).
• Tracking A , year 2021, month 2 the total will be one. (because there is only one record with the same year, month, and order).
• Tracking A , year 2021, month 3 the total will be two. (because there are two orders within the same year and month).
So the expected SELECT output will be like that:
TrackingStatus
Year
Month
Total
F
2020
1
1
E
2020
2
1
A
2021
2
1
A
2021
3
2
I was trying to use group by but then it will count the number of records which in my scenario is wrong.
How can I get the total orders for each month without counting “duplicate” records?
Thank you
You can use a COUNT DISTINCT aggregation function, whereas the COUNT allows you to count the values, but the DISTINCT condition will allow each value only once.
SELECT TrackingStatus,
Year,
Month,
COUNT(DISTINCT Order) AS Total
FROM tab
GROUP BY TrackingStatus,
Year,
Month
ORDER BY Year,
Month
Here you can find a tested solution in a MySQL environment, though this should work with many DBMS.

SQL Server 2008: How do you SUM based on two conditions?

If I work at a grocery store and need to make orders for inventory, we make orders multiple times a month rather than one large order.
Item
ETA
QTY
Apples
5/6/21
10
Apples
6/12/21
15
Apples
6/30/21
10
Bananas
6/12/21
15
Bananas
7/5/21
20
Cereal
5/15/21
10
Cereal
5/30/21
50
Cereal
7/15/21
20
Is there a way to create a table that sums the QTY, if the item is the same and if the ETA month is the same to know how much of each Item is expected to arrive in a given month?
Ideally, the result I'm looking for is something that looks like this
Item
May
June
July
Apples
10
25
0
Bananas
0
15
20
Cereal
60
0
20
I would need the code to first check to see what month the item is expected to arrive in, and then if there are more than one lines that have the same item and ETA month, SUM the QTY.
I have tried doing CASE WHEN statements but always end up with syntax errors
SELECT
CASE WHEN ETA BETWEEN '2021-05-01' AND '2021-05-31'
AND WHERE Item IN
(SELECT Item
FROM ['Inventory']
GROUP BY Item HAVING COUNT(*)>1)
THEN SUM(QTY)
END AS MAY_QTY
FROM [dbo].['Inventory'];
You just use conditional aggregation:
select item,
sum(case when month(eta) = 5 then qty else 0 end) as may,
sum(case when month(eta) = 6 then qty else 0 end) as jun,
sum(case when month(eta) = 7 then qty else 0 end) as jul
from inventory i
group by item;
I would caution you that using months without a year may lead to problems. That is also true of using unsupported software -- SQL Server 2008 is no longer supported.
First you should group the data by item and month, and then use pivot to convert rows to columns.
select
item,
isnull(may,0) as May,
isnull(june,0) as June,
isnull(july,0) as July
from
(
select item, datename(month, ETA) as _month, sum(qty) as qty
from Inventory
group by item, datename(month, ETA)
) d
pivot
(
sum(qty)
for _month in (may, june, july)
) piv;

SQL Nested Multiple Select Statement

Im trying to create a nested SQL statement with multiple Nested Select Statements, to be used on a record set import in excel vba.
What i want to do is create something like:
SELECT
N.LimitN,
Sum(N.amountN),
Sum(N1.amountN1)
FROM (
SELECT year as yearN, Sum(amount) as amountN, limit as limitN
FROM table1
WHERE year = 2013
GROUP BY year, limit) as N
JOIN (
SELECT year as yearN1, Sum(amount) as amountN1, limit as limitN1
FROM table1
WHERE year = 2014
GROUP BY year, limit) as N1
ON N.LimitN = N1.LimitN1
GROUP BY N.LimitN
ORDER BY N.LimitN;
So that if my Raw data is like this:
Year Amount Limit
2013 100 20
2013 90 30
2013 120 40
2013 5 20
2013 100 30
2013 105 40
2013 150 50
2014 115 20
2014 50 30
2014 95 40
2014 110 50
2014 30 20
My Resulting Table/record set will be like this:
Limit AmountN (i.e. 2013) Amount N1 (i.e. 2014)
20 105 145
30 190 50
40 225 95
50 150 110
Thanks in Advance
Peter
It feels like you're overcomplicating the query a little, what you want is just a year wise sum of amount, grouped by limit. This can be done using a CASE;
SELECT
limit,
SUM(CASE WHEN year=2013 THEN amount ELSE 0 END) amountN,
SUM(CASE WHEN year=2014 THEN amount ELSE 0 END) amountN1
FROM myTable
GROUP BY limit
ORDER BY limit;
An SQLfiddle to test with.
(if we're talking Access here, you will need to use IIF instead of CASE)

Generate year to date by month report in SQL [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Running total by grouped records in table
I am trying to put together an SQL statement that returns the SUM of a value by month, but on a year to date basis. In other words, for the month of March, I am looking to get the sum of a value for the months of January, February, and March.
I can easily do a group by to get a total for each month by itself, and potentially calculate the year to date value I need in my application from this data by looping through the results set. However, I was hoping to have some of this work handled with my SQL statement.
Has anyone ever tackled this type of problem with an SQL statement, and if so, what is the trick that I am missing?
My current sql statement for monthly data is similar to the following:
Select month, year, sum(value) from mytable group by month, year
If I include a where clause on the month, and only group by the year, I can get the result for a single month that I am looking for:
select year, sum(value) from mytable where month <= selectedMonth group by year
However, this requires me to have a particular month pre-selected or to utilize 12 different SQL statements to generate one clean result set.
Any guidance that can be provided would be greatly appreciated!
Update: The data is stored on an IBM iSeries.
declare #Q as table
(
mmonth INT,
value int
)
insert into #Q
values
(1,10),
(1,12),
(2,45),
(3,23)
select sum(January) as UpToJanuary,
sum(February)as UpToFebruary,
sum(March) as UpToMarch from (
select
case when mmonth<=1 then sum(value) end as [January] ,
case when mmonth<=2 then sum(value) end as [February],
case when mmonth<=3 then sum(value) end as [March]
from #Q
group by mmonth
) t
Produces:
UpToJanuary UpToFebruary UpToMarch
22 67 90
You get the idea, right?
NOTE: This could be done easier with PIVOT tables but I don't know if you are using SQL Server or not.
As far as I know DB2 does support windowing functions although I don't know if this is also supported on the iSeries version.
If windowing functions are supported (I believe IBM calls them OLAP functions) then the following should return what you want (provided I understood your question correctly)
select month,
year,
value,
sum(value) over (partition by year order by month asc) as sum_to_date
from mytable
order by year, month
create table mon
(
[y] int not null,
[m] int not null,
[value] int not null,
primary key (y,m))
select a.y, a.m, a.value, sum(b.value)
from mon a, mon b
where a.y = b.y and a.m >= b.m
group by a.y, a.m, a.value
2011 1 120 120
2011 2 130 250
2011 3 500 750
2011 4 10 760
2011 5 140 900
2011 6 100 1000
2011 7 110 1110
2011 8 90 1200
2011 9 70 1270
2011 10 150 1420
2011 11 170 1590
2011 12 600 2190
You should try to join the table to itself by month-behind-a-month condition and generate a synthetic month-group code to group by as follows:
select
sum(value),
year,
up_to_month
from (
select a.value,
a.year,
b.month as up_to_month
from table as a join table as b on a.year = b.year and b.month => a.month
)
group by up_to_month, year
gives that:
db2 => select * from my.rep
VALUE YEAR MONTH
----------- ----------- -----------
100 2011 1
200 2011 2
300 2011 3
400 2011 4
db2 -t -f rep.sql
1 YEAR UP_TO_MONTH
----------- ----------- -----------
100 2011 1
300 2011 2
600 2011 3
1000 2011 4