SQL: Getting Duplicate Data When Attempting to Sum and Join 2 Tables - sql

In Essence, I have two tables (purchases and sales) that I need to join together. Both tables have different Primary Keys, but they share the same foreign key. Every time a purchase is made, a new entry is made (with it's own primary key). Every time a sale is made, a new entry is made (with its own key).
Summary of Used Tables:
Purchase Data
Individual Product Cost (AS IPC)
Sales Tax (AS ST)
Quantity (AS Q)
SKU (Foreign Key)
Primary Key (AS PK)
Sales
Amount Sold (AS AS)
Total (AS T)
SSKU(Foreign Key)
Primary Key (AS PK)
When I attempt to Sum and Join the data based on the product I get weird results.
Purchase Table Data:
SKU | IPC | ST | Q | PK
1 2.40 .02 5 1
2 5.00 .05 20 2
3 4.00 .04 5 3
1 5.00 .04 20 4
Sales Table:
SSKU | T | AS | PK
1 10 2 1
2 9 1 2
3 9 4 3
1 9 1 4
2 9 2 5
1 9 2 6
1 9 4 7
Expected Results
SKU | (IPC + ST)Q | Q | SUM AS | SUM T
1 354.9 25 9 37
2 101 20 3 9
3 80.8 5 4 18
When trying the script creator in OpenOffice Base, It would give me the expected results for product 3, but it would be wrong for products 1 and 2.
I read up on SQL programming, and attempted my hand at it. I THINK this would solve the issue by summing the two tables separately before merging. Instead, I keep receiving an error now, and I can't find the mistake.
Current Code:
SELECT
"A"."SKU"
,SUM(( "A"."Individual Product Cost" + "A"."Sales Tax" ) * "A"."Quantity")
,"A"."Quantity"
,"D"."Sales"
,"D"."Sold"
FROM "PurchaseData" AS "A"
Inner Join
(
Select
"ACT"."SSKU"
,SUM("ACT"."Amount Sold") AS Sold
,SUM("ACT"."Total") AS Sales
From
"Sales" AS ACT
GROUP BY
"ACT"."SSKU"
)
AS D
on "A"."SKU" = "D"."SSKU"
Group By
"A"."SKU"
EDIT:
According to a random online Syntax checker, it's line 3 (I don't see it).
According to Openoffice Base:
SQL Status: HY000
Error code: 1000
syntax error, unexpected $end, expecting BETWEEN or IN or SQL_TOKEN_LIKE

Thanks to Jayvee, I got it working!
Select
"A"."SKU"
,"B"."Sold"
,"B"."Sales"
,"A"."Total Cost"
,"A"."Total Purchased"
From
-- First Sub Query --
(
Select
"PD"."SKU" As SKU
,SUM(( "PD"."Individual Product Cost" + "PD"."Sales Tax" ) *"PD"."Quantity") AS "Total Cost"
,SUM ("PD"."Quantity") AS "Total Purchased"
From
"PurchaseData" AS PD
GROUP BY
"PD"."SKU"
)
As A
--End First--
Join
--Start 2nd--
(
Select
"ACT"."SSKU" AS ASKU
,SUM("ACT"."Amount Sold") AS Sold
,SUM("ACT"."Total") AS Sales
From
"Sales" As ACT
GROUP BY
"ACT"."SSKU"
)
As B
--End 2nd--
On
"B"."ASKU" = "A"."SKU"

you can sum purchase data in a subquery, the same as you did with sales, and then join both subqueries without aggregation:
Select
"A"."SKU"
,"B"."Sold"
,"B"."Sales"
,"A"."Total Cost"
,"A"."Total Purchased"
From
-- First Sub Query --
(
Select
"PD"."SKU" As SKU
,SUM(( "PD"."Individual Product Cost" + "PD"."Sales Tax" ) *"PD"."Quantity") AS "Total Cost"
,SUM ("PD"."Quantity") AS "Total Purchased"
From
"PurchaseData" AS PD
GROUP BY
"PD"."SKU"
)
As A
--End First--
Join
--Start 2nd--
(
Select
"ACT"."SSKU" AS ASKU
,SUM("ACT"."Amount Sold") AS Sold
,SUM("ACT"."Total") AS Sales
From
"Sales" As ACT
GROUP BY
"ACT"."SSKU"
)
As B
--End 2nd--
On
"B"."ASKU" = "A"."SKU"

Related

Multiple select statements - Single result

I have a product list view and a v1 value which is used for mapping
For example in erp view it look like below
PRODUCT_ID
PRODUCT_NAME
QUANTITY
v1
1
WOOD PALLET 120x80
10
25
2
WOOD PALLET 200x80
5
25
25
RAW MATERIAL WOOD
100
25
in postgres we have for it 2 tables
Table: PRODUCTS
PRODUCT_ID
PRODUCT_NAME
QUANTITY
1
WOOD PALLET 120x80
10
2
WOOD PALLET 200x80
5
25
RAW MATERIAL WOOD
100
Table: PRODUCTS_MAPPING
PRODUCT_ID
MAPPING_KEY
1
25
2
25
25
25
Now I need a query that will give only one row result which is total of quantity grouped by v1 so result should be 115
I try below query
(
SELECT
SUM( pr.quantity )
FROM
products AS pr
WHERE
pr.product_id = ( SELECT map.product_id FROM products_mapping AS map WHERE mapping_key = v1 )
)
My problem is that after WHERE there is second SELECT statement which is giving multiple results. I need a statement which will do below calculation:
Check v1 value (25)
Go to product mapping table. Find 3 entry for mapping key 25.
Go to Product table and sum quantity for products_id 1,2,3 and give result 10+5+100 = 115
If I understood properly you only want a single result but you haven't put a group by clause in your sentence.
SELECT sum(pr.quantity) FROM products pr JOIN products_mapping map
on pr.product_id=map.product_id WHERE
mapping_key=v1 group by map.mapping_key
I have rewritten your statement using joins.

Group by with set of values in PostgreSQL

I have a product table:
productid product
1 A-110
2 B-110
3 C-400
4 D-401
And orderditems table:
orderitemid productid qty
1 1 10
2 2 10
3 3 10
4 3 10
5 4 10
I can group by based on product as:
select productid, sum(qty)
from ordereditems
group by productid
Which gives:
1 10
2 10
3 20
4 10
However for this query productid 1 & 2 , 3 & 4 are the same.
Meaning that I want to see:
1 + 2 20
3 + 4 30
Basically I want the query to understand that 1 & 2 are the same group and 3 & 4 are the same group.
How can i do that?
Edit:
Products 1 & 2 , 3 & 4 are not the same. However they are of the same family... What I want is to see how much we sell per family and not per product.
This is why the desired out put is:
1 + 2 20
3 + 4 30
A hacky version if you know that 1&2 are the same and 3&4 are the same, and those are the only things the same.
select
case
when productid in (1,2) then '1 + 2'
when productid in (3,4) then '3 + 4'
else productid
end as product_ids, sum(qty)
from ordereditems
group by
case
when productid in (1,2) then '1 + 2'
when productid in (3,4) then '3 + 4'
else productid
end
A better approach is to record in the database that two products are the same. Either by linking the duplicated products (2,4) to the product they're the same as (1,3) or by creating a new table family etc. and recording that products 1,2 are related to the same family.
family
familyid name
1 1+2
2 3+4
Extend product table
productid product familyid
1 A-110 1
2 B-110 1
3 C-400 2
4 D-401 2
then you can group on family
select f.name, sum(qty)
from ordereditems oi
inner join product p on oi.productid = p.productid
inner join family f on p.familyid = f.familyid
group by f.name
Pls add a GroupID/Category field to your table.
productid product GroupID
1 A-110 A
2 B-110 A
3 C-400 B
4 D-401 B
Then use the query
select GroupID, sum(qty) as Sold
from ordereditems
group by GroupID
This will represent as group sale as if you have more than 10 products in a group your productid will make complicity to understand.
If it works for you pls mark as helpful.. :)

Need help on writing sql select statement

I have a question about selecting rows from a table.
For example I have a table which includes information about stock movements. I wish to select the product code, latest date, latest price of each product in the table.
Stock movements table
Stock Movement Code Product code Date Price
1 1 15.06.2015 9$
2 2 17.06.2015 10$
3 2 18.06.2015 8$
4 1 19.06.2015 7$
5 3 20.06.2015 11$
6 2 21.06.2015 12$
7 3 22.06.2015 13$
I wish to select the latest date,latest price of each product from above table.
For this example I am waiting a result like below.
Stock Movement Code Product code Date Price
4 1 19.06.2015 7$
6 2 21.06.2015 12$
7 3 22.06.2015 13$
Could you please help me to write the SQL of this select statement?
Try this:
SELECT sm.*
FROM stock_movement sm
WHERE NOT EXISTS(
SELECT 'NEXT'
FROM stock_movement sm2
WHERE sm2.[Product code] = sm.[Product code]
AND sm2.date > sm.date
)

Microsoft SQL - Counting total of matching values in other table

I have a SQL data scructure like this.
Table 1
http://pbrd.co/1x6TAl3
Table 2
http://pbrd.co/1x6TIRw
I'm trying to count the number of times each item_num has been sold based on the item_qty value in the second table.
Each item_num can appear multiple times in the second table.
I need a way to add the total item_qty for each associated item_num and output it to show how many times an item has been sold.
The correct output ordering by total quantity sold in descending order should look like this.
item_num: 4 7 6
qty_sold: 11 5 4
Try this:
SELECT
a.item_num
, SUM(b.item_qty) as "qty_sold"
FROM
Table1 a
LEFT JOIN
Table2 b
ON a.item_num = b.item_num
GROUP BY
a.item_num
ORDER BY
qty_sold DESC
SELECT A.Item_num , A.Item_name , sum(B.Item_Qty) from Table1 as A inner join Table2 as B
on A.Item_num=B.Item_num
group by A.Item_num , A.Item_name
result:
item_num item_name Item_qty
1 A 1
2 B 1
4 D 11
6 F 4
7 G 5

SUM aggregate function and Subquery -SQL

I'm using MS SQL Server and I have 2 tables.
Supply_list
sl_id(pk) supply_id(fk)* transaction_id Qty
1 14 872670099 3
2 15 872670100 5
3 16 872670101 1
4 16 872670105 4 <
supply_id is a foreign key to the supply_id in amenity table
Supply
supply_id(pk) no_of_units
----------------------------
13 2
14 3
15 6
16 10
The output should be supply_id then the no. of units available which is equal to No_of_units subtracted by the Qty.
output
id units available
-------------------------
13 2
14 0 --> [1]
15 1
16 5 --> [2]
[1] Since based on the supply_list table supply_id 14 has 3 for its Qty
[2] There are two records that contains supply_id 16 so we have to add their qty which are 4 and 1 so we have 5. And that 5 would be subtracted from the no_of_units of supply_id 16 and we will get 5 for units available.
You left outer JOIN the list table to the parent table
Subtract the SUM of the list Qty values from the parent no_of_units value
Use ISNULL in case there are no list rows
Something like
SELECT
S.supply_id,
S.no_of_units - ISNULL(SUM(SL.Qty), 0) AS [units available]
FROM
supply S
LEFT JOIN
supply_list SL ON S.supply_id = SL.supply_id
GROUP BY
S.supply_id, S.no_of_units
This makes the aggregate more obvious but is the same query
SELECT
S.supply_id,
S.no_of_units - ISNULL(SL.SumListQty, 0) AS [units available]
FROM
supply S
LEFT JOIN
(
SELECT supply_id, SUM(Qty) AS SumListQty
FROM supply_list
GROUP BY supply_id
) SL ON S.supply_id = SL.supply_id