Impala/Hive - Sum up the amount for Adjustment code - hive

I have an Impala table named REV having wire_code and amount for each wire code
+---------+------+
|wire_code| amt |
+---------+------+
| abc | 100 |
+---------+------+
| def | 50 |
+---------+------+
| ghi | 250 |
+---------+------+
| jkl | 300 |
+---------+------+
and the other table is FA which is having wire_code and Ajusted_wire_code.
+---------+------+
|wire_code|adj_wc|
+---------+------+
| abc | def |
+---------+------+
| ghi | jkl |
+---------+------+
I need to adjust the amount of wire code which is available as adj_wc in FA table.
For example:
"abc" is there in FA table and its getting adjusted to "def" then my output should be - wire_code "def" is having amount of (abc+def) as below.
"abc" amount will remain same.
+---------+------+
|wire_code| amt |
+---------+------+
| abc | 100 |
+---------+------+
| def | 150 |
+---------+------+
| ghi | 250 |
+---------+------+
| jkl | 550 |
+---------+------+
Please help in this query.
Thanks in Advance!

Using two joins:
select r.wire_code, r.amt+coalesce(a.amt,0) as amt
from REV r
left outer join FA f on r.wire_code=f.adj_wc --adjustments
left outer join REV a on f.wire_code=a.wire_code --adjusted amount
;

Related

how to do dynamic sum and substraction [duplicate]

I have a table in an Oracle db that has the following fields of interest: Location, Product, Date, Amount. I would like to write a query that would get a running total of amount by Location, Product, and Date. I put an example table below of what I would like the results to be.
I can get a running total but I can't get it to reset when I reach a new Location/Product. This is the code I have thus far, any help would be much appreciated, I have a feeling this is a simple fix.
select a.*, sum(Amount) over (order by Location, Product, Date) as Running_Amt
from Example_Table a
+----------+---------+-----------+------------+------------+
| Location | Product | Date | Amount |Running_Amt |
+----------+---------+-----------+------------+------------+
| A | aa | 1/1/2013 | 100 | 100 |
| A | aa | 1/5/2013 | -50 | 50 |
| A | aa | 5/1/2013 | 100 | 150 |
| A | aa | 8/1/2013 | 100 | 250 |
| A | bb | 1/1/2013 | 500 | 500 |
| A | bb | 1/5/2013 | -100 | 400 |
| A | bb | 5/1/2013 | -100 | 300 |
| A | bb | 8/1/2013 | 250 | 550 |
| C | aa | 3/1/2013 | 550 | 550 |
| C | aa | 5/5/2013 | -50 | 600 |
| C | dd | 10/3/2013 | 999 | 999 |
| C | dd | 12/2/2013 | 1 | 1000 |
+----------+---------+-----------+------------+------------+
Ah, I think I have figured it out.
select a.*, sum(Amount) over (partition by Location, Product order by Date) as Running_Amt
from Example_Table a
from Advanced SQL Functions in Oracle 10g book, it has this example.
SELECT dte "Date", location, receipts,
SUM(receipts) OVER(ORDER BY dte
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) "Running total"
FROM store
WHERE dte < '10-Jan-2006'
ORDER BY dte, location
I could type out all the answer or send you to where I learned it. :)
Check this out, it explains exactly what you are trying to do.
http://www.codeproject.com/Articles/300785/Calculating-simple-running-totals-in-SQL-Server

Ms access duplicated records

I`m having an issue with my MS Access query and I hope you can help me.
I want product "ABC" to have code "6029" if the parent is anything else than "GYF", "RGY" & "DRF".
The mapping looks as follows:
| Output_code | Account | Product | Parent |
+-------------+---------+----------+--------+
| 6029 | income | ABC | |
| 7029 | income | ABC | GYF |
| 7029 | income | ABC | RGY |
| 7029 | income | ABC | DRF |
+-------------+---------+----------+--------+
End result would be:
+-------------+---------+----------+--------+
| 6029 | income | ABC | DTF |
| 6029 | income | ABC | DHS |
| 7029 | income | ABC | GYF |
| 7029 | income | ABC | RGY |
| 7029 | income | ABC | DRF |
+-------------+---------+----------+-------
How it works right now:
+-------------+---------+----------+--------+
| 6029 | income | ABC | DTF |
| 6029 | income | ABC | DHS |
| 7029 | income | ABC | GYF |
| 7029 | income | ABC | RGY |
| 7029 | income | ABC | DRF |
| 6029 | income | ABC | GYF |
| 6029 | income | ABC | RGY |
| 6029 | income | ABC | DRF |
+-------------+---------+----------+--------+
Select A.*, B.Output_Code, "Product" as Comment from Source as A
inner join Mapping as B on (B.Account=A.Account and B.Product = A.Product)
where (B.Parent = "" or B.Parent <> A.Parent);
union all
Select A.*, B.Output_Code, "Product+Parent" as Comment from Source as A
inner join Mapping as B on (B.Account=A.Account and B.Product = A.Product
and A.Parent = B.Parent) where B.Parent <> "";
First part (Product) is not working as expected and combinations like ABC+RGY appear twice with both "6029" and "7029".
I tried using select within select (for this I introduced rowid) and it worked but right now is takes 30 min for my query to process (instead of 5 min).
Select A.*, B.Output_Code, "Product" as Comment from Source as A inner join
Mapping as B on (B.Account=A.Account and B.Product = A.Product)
where (B.Parent = "" or B.Parent <> A.Parent) and A.rowid not in (Select
A.rowid from Source as A inner join Mapping as B on (B.Account=A.Account and
B.Product = A.Product and A.Parent = B.Parent) where B.Parent <> "");
Could you kindly share your ideas on what is the proper way of building the first query so it doesn`t affect the performance so heavily?
I went through the list of questions but couldn`t find anything similar.
"Go for the simple solution, not the perfect one"
SELECT
IIF(Parent IN ('GYF','RGY','DRF'), 7029, 6029) as Output_code
FROM
Product
PS; i don't really do much Access SQL- i might not have used the correct string delimiters etc - you might need to jiggle this query around a bit
Edit: If you're looking to extend the mapping, you should consider a left join instead:
Select s.*, IIF(m.Output_Code IS NULL, 6029, m.output_Code)
FROM
source s
LEFT OUTER JOIN
mapping m
on (m.Account=s.Account and m.Product = s.Product and m.parent = s.parent)
Remove the 6029 row from the mapping table (redundant)
LEFT JOIN connects rows that match, and keeps rows from the left side (source) that don't have a match in the right (map) but puts nulls in the values for the right side. By comparison, an inner join throws away rows that don't have a match. It's the "this row from source has no match in map" quality that we want to leverage
This means the 'GYF','RGY','DRF' rows WILL have a match in the map table, they will not be null, the IIF will be false for those rows, the code from mapping will be used
Other rows will NOT have a match, the m.Output_code for those rows will be NULL, the IIF will be TRUE, the value 6029 will be used
I'll make a couple of assumptions about your base tables.
Your Mapping table looks like this:
| Output_code | Product | Parent |
|-------------|---------|--------|
| 7029 | ABC | DRF |
| 7029 | ABC | GYF |
| 7029 | ABC | RGY |
| 8593 | DEF | XYZ |
Your Source table looks like this:
| Product | Parent |
|---------|--------|
| ABC | DTF |
| ABC | DHA |
| ABC | GYF |
| ABC | RGY |
| ABC | DRF |
| DEF | XYZ |
| DEF | ZXL |
This SQL will return all your Source values with the correct Output_code attached. A Null value is returned where there is no Output_code:
SELECT Mapping.Output_code
, Source.Product
, Source.Parent
FROM Source LEFT JOIN Mapping ON Source.Product = Mapping.Product AND
Source.Parent = Mapping.Parent
| Output_code | Product | Parent |
|-------------|---------|--------|
| | ABC | DTF |
| | ABC | DHA |
| 7029 | ABC | GYF |
| 7029 | ABC | RGY |
| 7029 | ABC | DRF |
| 8593 | DEF | XYZ |
| | DEF | ZXL |
If the only product is ABC and you only want to to replace all NULL values with 6029 you could update the Mapping.Output_code line to NZ(Mapping.Output_code, 6029) to do this.
Nz Function help
SELECT NZ(Mapping.Output_code,6029)
, Source.Product
, Source.Parent
FROM Source LEFT JOIN Mapping ON Source.Product = Mapping.Product AND
Source.Parent = Mapping.Parent
| Expr1000 | Product | Parent |
|----------|---------|--------|
| 6029 | ABC | DTF |
| 6029 | ABC | DHA |
| 7029 | ABC | GYF |
| 7029 | ABC | RGY |
| 7029 | ABC | DRF |
| 8593 | DEF | XYZ |
| 6029 | DEF | ZXL |
But I expect you have more than one product and want product DEF to show a different value if there's no parent available.
To do this add a third table called NoMap that lists the code for any product that doesn't already have one:
| Product | Output_code |
|---------|-------------|
| ABC | 6029 |
| DEF | 7593 |
Primary Key: Product
You can then use this new table to replace any Null values found in your table:
SELECT NZ(Mapping.Output_code, NoMap.Output_code)
, Source.Product
, Source.Parent
FROM (
Source LEFT JOIN Mapping ON Source.Product = Mapping.Product AND
Source.Parent = Mapping.Parent)
LEFT JOIN NoMap ON Source.Product = NoMap.Product
| Expr1000 | Product | Parent |
|----------|---------|--------|
| 6029 | ABC | DTF |
| 6029 | ABC | DHA |
| 7029 | ABC | GYF |
| 7029 | ABC | RGY |
| 7029 | ABC | DRF |
| 8593 | DEF | XYZ |
| 7593 | DEF | ZXL |
You can use this.
Select A.*, NZ(B1.Output_Code, B2.Output_Code) as "Output_Code" from
(Source as A
left join Mapping as B1 on (B1.Account=A.Account and B1.Product = A.Product and B1.Parent = A.Parent ) )
left join Mapping as B2 on (B2.Account=A.Account and B2.Product = A.Product and (B2.Parent Is Null or B2.Parent ="") )

Calculate Weighted Average in sql for duplicate items

TABLE
ITEM | SKU | QUANT | ITEM LANDING
-----+-------+---------+-----------------
ABC | A-B-C | 5 | 500
ABC | A-B-C | 10 | 400
DEF | D-E-F | 5 | 200
GHI | G-H-I | 6 | 300
JKL | J-K-L | 5 | 800
JKL | J-K-L | 10 | 600
RESULT
ITEM NAME | ITEM SKU | QUANT | Weighted Average
----------+-----------+--------+---------------------
ABC | A-B-C | 15 | 433.33
DEF | D-E-F | 5 | 200
GHI | G-H-I | 6 | 300
JKL | J-K-L | 15 | 666.66
I want to calculate weighted average for duplicate items
((first landing *qty)+(second landing *qty))/(sum(qty)
SELECT ITEMNAME, ITEMSKU, SUM(QUANT), SUM(QUANT * ITEM_LANDING) / SUM(QUANT)
FROM <YourTable>
GROUP BY ITEMNAME, ITEMSKU
Try this...
QUERY
SELECT item_name AS 'ITEM NAME',
item_sku AS ' ITEM SKU',
SUM(quant) AS 'QUANT',
(SUM(quant*item_landing)/sum(quant)) AS 'ITEM LANDING'
FROM items
GROUP BY item_name;
SQL FIDDLE

Move values from 1 column to multiple rows organized by a unique identifier MSAccess/SQL

SQL newbie here. I have a work task that I'm trying to expidite by using MSAccess/SQL as they are what I am most familiar with!
I have a spreadsheet with over 6000 unique rows that looks like this:
| SampleID | Unique ID |
| 123 | ABC |
| 124 | ABC |
| 125 | ABC |
| 456 | DEF |
| 457 | DEF |
| 458 | DEF |
| 789 | GHI |
| 790 | GHI |
| 791 | GHI |
| 792 | GHI |
And I'd like to move the values from SampleID into individual columns, based on the UniqueID, like so:
| UniqueID | SampleID1 | SampleID2 | SampleID3 | SampleID4 |
| ABC | 123 | 124 | 125 | |
| DEF | 456 | 457 | 458 | |
| GHI | 789 | 790 | 791 | 792 |
I'm attempting to do this in SQL/MSAccess using queries on an imported excel table that has over 6000 rows.
I've managed to count the maximum number Samples per a UniqueID: 55.
Is there a way to use pivot based grouped by the UniqueID? How should I / how does MSAccess/SQL handle null values?
You can use Pivot for the same...
select *
from
(
select SampleID, unique_id
from table1
) x
pivot
(
max(unique_id)
for SampleID in ([Sample1], [Sample3], [Sample3], [Sample4],....)
) p

Running Total by Group SQL (Oracle)

I have a table in an Oracle db that has the following fields of interest: Location, Product, Date, Amount. I would like to write a query that would get a running total of amount by Location, Product, and Date. I put an example table below of what I would like the results to be.
I can get a running total but I can't get it to reset when I reach a new Location/Product. This is the code I have thus far, any help would be much appreciated, I have a feeling this is a simple fix.
select a.*, sum(Amount) over (order by Location, Product, Date) as Running_Amt
from Example_Table a
+----------+---------+-----------+------------+------------+
| Location | Product | Date | Amount |Running_Amt |
+----------+---------+-----------+------------+------------+
| A | aa | 1/1/2013 | 100 | 100 |
| A | aa | 1/5/2013 | -50 | 50 |
| A | aa | 5/1/2013 | 100 | 150 |
| A | aa | 8/1/2013 | 100 | 250 |
| A | bb | 1/1/2013 | 500 | 500 |
| A | bb | 1/5/2013 | -100 | 400 |
| A | bb | 5/1/2013 | -100 | 300 |
| A | bb | 8/1/2013 | 250 | 550 |
| C | aa | 3/1/2013 | 550 | 550 |
| C | aa | 5/5/2013 | -50 | 600 |
| C | dd | 10/3/2013 | 999 | 999 |
| C | dd | 12/2/2013 | 1 | 1000 |
+----------+---------+-----------+------------+------------+
Ah, I think I have figured it out.
select a.*, sum(Amount) over (partition by Location, Product order by Date) as Running_Amt
from Example_Table a
from Advanced SQL Functions in Oracle 10g book, it has this example.
SELECT dte "Date", location, receipts,
SUM(receipts) OVER(ORDER BY dte
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) "Running total"
FROM store
WHERE dte < '10-Jan-2006'
ORDER BY dte, location
I could type out all the answer or send you to where I learned it. :)
Check this out, it explains exactly what you are trying to do.
http://www.codeproject.com/Articles/300785/Calculating-simple-running-totals-in-SQL-Server