sum two row with condition - sql

I have one table as below if two rows has same item and location then two one should become one one row and give the total of qty
item location qty
a 1010 10
a 1020 5
a 1010 5
b 1010 2
b 1010 5
b 1020 1
c 1010 5
result
item location qty
a 1010 15
a 1020 5
b 1010 7
b 1020 1
c 1010 5

SELECT item, location, SUM(qty)
FROM xTable
GROUP BY item, location

SELECT t.item, t.location, SUM(t.qty)
FROM test t
GROUP BY t.item, t.location
ORDER BY t.item, t.location

Related

How to get the sum of each children into its parent node using psql?

So, I have hierarchy table where I want the sum of children (cumulative sum) added to all parent.
I have 2 tables dimension and valuation. I need to sum up volumeimpact based on a dimension tree.
http://sqlfiddle.com/#!15/5c0e7/5
id dimensionvalueid name volume cumulativeSum
1 (null) one (null) 700
2 1 five 200 700
3 2 sixteen 200 500
4 3 eighteen 200 300
5 3 random 100 100
6 (null) root 300
7 6 yellow 100 300
8 6 orange 100 200
9 8 green 100 100
It appears we don't have a handy grouping root column, so we can create it ourselves within your recursive function. Then we can partition by this root column and get our cumulative sum:
WITH RECURSIVE hierarchy AS (
SELECT
id,
name,
dimensionvalueid,
id root_id
FROM
dimensionvalue d
WHERE
dimensionvalueid IS NULL
UNION ALL
SELECT
e.id,
e.name,
e.dimensionvalueid,
hierarchy.root_id
FROM
dimensionvalue e,
hierarchy
WHERE
e.dimensionvalueid = hierarchy.id
)
select d.id, d.dimensionvalueid, d.name, v.volume, sum(v.volume) over(partition by root_id order by d.id desc) cumulativeSum
from hierarchy d
left join valuation v on v.dimensionvalueid = d.id

How to select distinct values for two and return all columns?

I want to select distinct values from two columns.
Example data:
ID TITLE SOURCE TARGET
1 asd 12 2
2 asd1 123 125
3 asd1 123 56
4 asd2 123 125
5 asd3 164 146
I want to get distinct data for source and target columns ID - 2 and ID - 4 are duplicates.
ID TITLE SOURCE TARGET
1 asd 12 2
2 asd1 123 125
3 asd1 123 56
5 asd3 164 146
If you just want the distinct values, use select distinct:
select distinct source, target
from example t;
If you want the rows where the source/target only appears on one row, then one method uses window functions:
select t.*
from (select t.*,
count(*) over (partition by source, target) as cnt
from example t
) t
where cnt = 1;

T SQL Cumulative Subtraction

I'm using MS SQL Server.
I have the below table:
SKU Shop WeekNum ShopPrioirty Replen OpeningStock
111 100 1 1 10 5000
111 200 1 2 10 NULL
111 300 1 3 5 NULL
111 400 1 4 8 NULL
222 100 2 1 20 6000
222 200 2 2 15 NULL
222 300 2 3 12 NULL
222 400 2 4 10 NULL
This is the desired result:
SKU Shop WeekNum ShopPrioirty Replen OpeningStock
111 100 1 1 10 5000
111 200 1 2 10 4990
111 300 1 3 5 4980
111 400 1 4 8 4975
222 100 2 1 20 6000
222 200 2 2 15 5980
222 300 2 3 12 5965
222 400 2 4 10 5953
For a given week, a SKU exists in multiple shops and is assigned a priority. At Priority 1 the opening stock is assigned.
However, I need to update the Opening Stock (where it is currently NULL) to equal the previous Opening Stock Minus the Previous Replen.
Before I attempt the update, I tried to just do a SELECT
SELECT SKU
,Shop
,WeekNum
,StorePriority
,Replen
,OpeningStock
,OpeningStock - Replen OVER (ORDER BY SKU,Shop,WeekNum ROWS UNBOUNDED PRECEDING) AS Opening
FROM [table1] t
But I receive the error:Incorrect syntax near the keyword 'OVER'.
Is a running sum the correct way to go?
Would it be best to create a key made up from the SKU\Shop\WeekNum\Priority?
Thanks.
I've made a couple of assumptions here on your PARTITION BY and ORDER BY clauses, but this gets you the result you're after. As you only have a value for OpeningStock in the first row for a SKU, then I use FIRST_VALUE to get the First Value, and then take away all prior values of Replen:
WITH VTE AS(
SELECT *
FROM (VALUES(111,100,1,1,10,5000),
(111,200,1,2,10,NULL),
(111,300,1,3,5 ,NULL),
(111,400,1,4,8 ,NULL),
(222,100,2,1,20,6000),
(222,200,2,2,15,NULL),
(222,300,2,3,12,NULL),
(222,400,2,4,10,NULL))V(SKU,Shop,WeekNum,ShopPrioirty,Replen,OpeningStock))
SELECT V.SKU,
V.Shop,
V.WeekNum,
V.ShopPrioirty,
V.Replen,
V.OpeningStock,
FIRST_VALUE(V.OpeningStock) OVER (PARTITION BY V.SKU ORDER BY V.ShopPrioirty,V.WeekNum ROWS UNBOUNDED PRECEDING) -
ISNULL(SUM(V.Replen) OVER (PARTITION BY V.SKU ORDER BY V.ShopPrioirty,V.WeekNum ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),0) AS CurrentStock
FROM VTE V;

SELECT clause with SUM condition

Have this table :
//TEST
NUMBER TOTAL
----------------------------
1 158
2 355
3 455
//TEST1
NUMBER QUANTITY UNITPRICE
--------------------------------------------
1 3 5
1 3 6
1 3 4
2 4 8
3 5 4
I used following query:
SELECT t.NUMBER,sum(t.TOTAL),NVL(SUM(t2.quantity*t2.unitprice),0)
FROM test t INNER JOIN test1 t2 ON t.NUMBER=t2.NUMBER
GROUP BY t.NUMBER;
OUTPUT:
NUMBER SUM(TOTAL) SUM(t2.quantity*t2.unitprice)
-----------------------------------------------------------
1 474 45 <--- only this wrong
2 355 32
It seem like loop for three times so 158*3 in the record.
EXPECTED OUTPUT:
NUMBER SUM(TOTAL) SUM(t2.quantity*t2.unitprice)
-----------------------------------------------------------
1 158 45
2 355 32
You have to understand that the result of your join is something like this:
//TEST1
NUMBER QUANTITY UNITPRICE TOTAL
--------------------------------------------------------------
1 3 5 158
1 3 6 158
1 3 4 158
2 4 8 355
3 5 4 455
It means you don't need to apply a SUM on TOTAL
SELECT t.NUMBER,t.TOTAL,NVL(SUM(t2.quantity*t2.unitprice),0)
FROM test t INNER JOIN test1 t2 ON t.NUMBER=t2.NUMBER
GROUP BY t.NUMBER, t.TOTAL;
Something like this should work using a subquery separating the sums:
select t.num,
sum(t.total),
test1sum
from test t
join (
select num, sum(qty*unitprice) test1sum
from test1
group by num
) t2 on t.num = t2.num
group by t.num, test1sum
SQL Fiddle Demo
In regards to your sample data, you may not even need the additional group by on the test total field. If that table only contains distinct ids, then this would work the same:
select t.num,
t.total,
sum(qty*unitprice)
from test t
join test1 t2 on t.num = t2.num
group by t.num, t.total

Use column from first table as condition for joining second table

Suppose I have
products:
folio price quantity
1 100.00 1
1 450.00 2
3 150.00 1
4 600.00 2
terms:(to know how many payment terms depending on the price of the product)
level term
0.01 12
100.00 14
200.00 16
300.00 18
400.00 20
500.00 22
What can I do to have a resulting table like this:
folio price quantity term
1 100.00 1 14
1 450.00 2 20
I've tried using:
SELECT a.*, b.term
FROM products AS a
JOIN terms AS b ON b.level <= a.price
WHERE a.folio = 1
But I end up getting:
folio price quantity term
1 100.00 1 12
1 100.00 1 14
1 450.00 2 12
1 450.00 2 14
1 450.00 2 16
1 450.00 2 18
1 450.00 2 20
What can I do so I only get the row with the biggest term? Please help!
You are looking for one row from the terms table, not all of them. One way to do this is with a correlated subquery:
SELECT p.*,
(select t.term from terms t where p.price >= t.level order by t.level desc limit 1
) as term
FROM products p
WHERE p.folio = 1;
If you can modify your terms table to have a minimum and maximum price, then that would make it easier to user.
And, you can mimic this with the lead() function:
select p.*, t.term
from products p left outer join
(select t.*, lead(level) over (order by level) as nextlevel
from terms t
) t
on p.price >= t.level and (p.price < t.nextlevel or t.nextlevel is null)
where p.folio = 1;