Select inside select - sql

A newbie here. So please be kind :-)
I have 2 Tables namely Item & Item Entries.
Relation is: Item.No = ItemEntries.No.
In Item Entries Table I have Columns as Qty, Entry type, Purchase Amount, Sales Amount
I like to have a report which shows as below,
Item No. | Opening Quantity | Purchase Amount | Sales Amount
To calculate Opening Inventory I summed up the quantity field and the result is as expected. No problem in that. Now From that dataset I like to run a sub query which Calculates/Sum the Purchase amount for an Item that is a part of first dataset and similarly for Sales Amount.
Select(Item No.,Sum(IE.Quantity) As Quantity, Select(......Purchase Amount),Select(....Sales Amount)
I hope I was able to clear my doubts to you guys.

Something like :
SELECT ItemNo, sum(quantity), purchaseAmount, SalesAmount FROM Item i INNER JOIN ItemEntities ie on i.no = ie.no GROUP BY ItemNo, PurchaseAmount, SalesAmount;

I believe (if I understand what you want) that this is the solution to your problem
Select Item.No ,
Sum(IE.Quantity) As Quantity,
(Select(......Purchase Amount)) As ColumnName1 ,
(Select(....Sales Amount)) As ColumnName2

From your need to "sum the purchase amount for an item that is part of the first dataset and similarly for Sales Amount" I think what you're trying to achieve is one row for each item on the Item table with a sum for each of the Qty, Sales Amount and Purchase Amount. If so, then you can simply use a 'group by' clause which groups results together which have matching values for the columns specified.
SELECT I.no, SUM(IE.qty), SUM(IE.purchase_amount), SUM(IE.sales_amount)
FROM item I JOIN item_entries IE
ON I.no = IE.no
GROUP BY I.no;
See the group_by_clause for more details and some examples.
N.B. The join from the item tables isn't strictly required in this example, but if you're producing a report I suspect you might want to get things like a description - in which case you'll need to add those columns to the group by clause too.

You might need the sum of three columns from
ItemEntries table(Qty,PurchaseAmount,SalesAmount) for each Item.No
Select A.No,
Sum(B.Qty),
Sum(B.Purchaseamount),
Sum(B.Salesamount)
From Item A,
Itementries B
Where A.No = B.No
Group By A.No;

Related

SQL query for calculated column

I have a table that looks like this -
Table screenshot link - https://i.stack.imgur.com/Pztpq.png
I want to add a new column 'Manufacturer_Updated', such that -
If any particular 'Product' has more than 1 (distinct) 'Manufacturer', then the Manufacturer having highest 'Sales' should be populated in the 'Manufacturer_Updated' column for all rows of that particular 'Product'.
Ex - In the above screenshot, Product - 'TOTAL HAIR CARE NA' has 2 different Manufacturer, so in the 'Manufacturer_Updated' column, 'SEXY HAIR CONCEPTS' should appear for both the rows, as it has the higher sales.
Could someone pls help with this query? Thanks in Advance!
Something like this should work:
SELECT Manufacturer, Product, Sales, Manufacturer as Manufacturer_Updated FROM
WHERE amt_of_manufacturers > 1
((SELECT Product, max(Sales) as Sales, count(distinct Manufacturer) as amt_of_manufacturers
FROM your_table
GROUP BY Product) as q1
left join
(SELECT Manufacturer, Sales, Product
FROM your_table
) as q2
ON q1.Sales = q2.Sales
AND q1.Product = q2.Product
) as q3
In the first query (q1), you're retrieving maximum sales per each product along with amount of manufacturers for a specific product (used later in upper query). In the second one (q2) you just need to retrieve Manufacturer (to transform it later to Manufacturer_Updated), Sales and Product (as join keys). After this you only need to filter out all products with single manufacturer.
Alternatively, if you want to keep those, you can remove where amt_of_manufacturers > 1 and replace Manufacturer_Updated in the upper query with the following:
CASE WHEN
amt_of_manufacturers <=1 THEN null
ELSE Manufacturer
END AS Manufacturer_Updated

Add and display all values

There are 2 tables called Item & Items_in_issue_Note(Items_in_issue_Note is a many to many table).
In Item table there is a column called Available_Qty and in Items_in_issue_Note there is a column called Issued_Qty.
I want to get the sum of Issued_Qty for each item and add it to Available_Qty in each item and display them item wise to get the Quantity before issue items.
I know how to get the sum of Issued_Qty by using
select ItemCode, sum(Issued_Qty)
from Items_In_Issue_Note
group by ItemCode
and how to get the Available_Qty by using
select itemCode,Available_Qty
from Item
and know how to get the quantity per item by using
select
itemCode,
Available_Qty + (select sum(Issued_Qty)
from Items_In_Issue_Note
where ItemCode='I001')
from Item
where ItemCode='I001'
But want to know how to get the output for all the items.
Thank you.
By using group by and join you may get the desired result. Try the following
select
A.itemCode,
A.Available_Qty + Coalesce(sum(B.Issued_Qty),0)
from Item A left join
Items_In_Issue_Note B on A.ItemCode=B.ItemCode
group by A.itemCode,A.Available_Qty
Your code modified below one is modified based on sub-query depends on main table value
select
itemCode,
Available_Qty + (select sum(Issued_Qty)
from Items_In_Issue_Note
where ItemCode=Item.ItemCode)
from Item
Best way is follow join instead of sub-query because sub-query gives performance issue.

Selecting first record name from duplicate values

I'm writing a query where I want to select the PartNo, Description, Model, and AvaQty from a view.
But in our system, there are slightly different Descriptions or Models for the same Part Number.
As an example, Part A has description like This is Part A and also there is another record for description like This is Part Aa
In my query, I want to remove duplicates and Sum the Ava Qty and show. But because the descriptions and model are different for the same part numbers I'm getting more duplicate values in the final report.
This is my current code.
SELECT DISTINCT PART_NO as PartNo,
ad.INVENTORY_PART_API.Get_Description(contract,part_no) as PartDescription,
ad.Inventory_Product_Family_API.Get_Description(ad.Inventory_Part_API.Get_Part_Product_Family(CONTRACT, PART_NO)) as PartModel,
SUM( QTY_ONHAND - QTY_RESERVED) as AvaQty
FROM ad.INVENTORY_PART_IN_STOCK_UIV
WHERE CONTRACT is not null and
upper(ad.Sales_Part_API.Get_Catalog_Group(CONTRACT, PART_NO)) = upper('SPAM')OR
upper(ad.Sales_Part_API.Get_Catalog_Group(CONTRACT, PART_NO)) = upper('OTOA')
GROUP BY PART_NO,
ad.INVENTORY_PART_API.Get_Description(contract,part_no),
ad.Inventory_Product_Family_API.Get_Description(ad.Inventory_Part_API.Get_Part_Product_Family(CONTRACT, PART_NO))
So I get 14623 counts of records, 46 records are duplicated because the description or model was different from each other. So is there any way to get this without duplicating it?
I tried without selecting Description and Model. Selected Only PartNo and Qty. Then records come without duplicate records. Need to know is there any way to select PartNo and then assign description and model from the duplicate values first record or something and sum of qty. Thanks
You want one result row per part number, so group by part number. There can be different descriptions per part number, so decide which to show. Below, I am showing the first in alphabet (MIN). You can also use MAX to show the latest or LISTAGG to show them all.
SELECT
part_no AS partno,
MIN(ad.inventory_part_api.get_description(contract,part_no)) AS partdescription,
MIN(ad.inventory_product_family_api.get_description(ad.inventory_part_api.get_part_product_family(contract, part_no))) AS partmodel,
SUM(qty_onhand - qty_reserved) AS avaqty
FROM ad.inventory_part_in_stock_uiv
WHERE contract IS NOT NULL
AND UPPER(ad.sales_part_api.get_catalog_group(contract, part_no)) IN ('SPAM', 'OTOA')
GROUP BY part_no
ORDER BY part_no;
As to your WHERE clause: You had WHERE (contract IS NOT NULL AND catgrp = 'SPAM') OR (catgrp = 'OTOA'), because AND has precedence over OR. In my query it is WHERE (contract IS NOT NULL) AND (catgrp = 'SPAM' OR catgrp = 'OTOA'). I suppose this is what you really want. Otherwise change it back.
I would solve this task by using analytic functions.
For example, SUM(qty_onhand - qty_reserved) OVER (PARTITION BY PART_NO). In this case you don't have to use GROUP BY.

Get the product of two values from two different tables

If anyone can help me figure out where I am going wrong with this SQL that would be great. Please see my attempt to answer it below. I have answer how I think it should be answered but I am very confused by the exam advice below, which says I should use a SUM function? I have googled this and I do not see how a SUM function can help here when I need get the product of two values in this case. Or am I missing something major?
Question: TotalValue is a column in Order relation that contains derived data representing total value (amount) of each order. Write a SQL SELECT statement that computes a value for this column.
My answer:
SELECT Product.ProductPrice * OrderLine.QuantityOrdered AS Total_Value
FROM Product,
OrderLine
GROUP BY Product;
Advice from exam paper:
This is a straightforward question. Tip: you need to use the SUM function. Also, note that you can take the sum of various records set using the GROUP BY clause.
Ok your question became a lot clearer once I clicked on the the hyperlink (blue text).
Each order is going to be made up of a quantity of 1 or more products.
So there could be 3 Product A and 5 Product B etc.
So you have to get the total for each product which is your Price * Quantity, but then you need to add them all together which is where the SUM comes in.
Example:
3 * ProductA Price (e.g. €5) = 15
5 * ProductB Price (e.g. €4) = 20
Total Value = 35
So you need to use the Product, Order and OrderLine tables.
Something like (I haven't tested it):
SELECT SUM(Product.ProductPrice * OrderLine.QuantityOrdered) FROM Product, Order, OrderLine
WHERE Order.OrderID = OrderLine.OrderID
AND Product.ProductID = OrerLine.ProductID
GROUP BY Order.OrderID
This should return rows containing the totalValue for each order - the GROUP BY clause causes the SUM to SUM over each group - not the entire rows.
For a single order you would need add (before the GROUP BY) "AND Order.OrderID = XXXXX" where XXXXX is the actual orders OrderId.

Multiple of same result even with group by

Alright so say I have a 'product_catalog', and 'orders' tables. Each order has the product_catalog_id as a foreign key. What I want to return as the query results is the product_code (name of the product associated with a specific product_catalog_id) + a count of how many of each product_code have been ordered. That's easy enough with something like this (Oracle SQL):
SELECT pc.product_code,
COUNT(*) as count
FROM orders o
join product_catalog pc on pc.product_catalog_id = o.product_catalog_id
GROUP BY pc.product_code
ORDER BY count DESC;
but I also want to print various pieces of information from the order table such as total of all monthly charges for that product_code. That would seem easy enough with something like this:
(o.monthly_base_charge*count(*)) as "Monthly Fee"
but the problem is that there have been various monthly fees for the same product_code over time. If I add the above line in and add 'o.monthly_base_charge' to the group by statement, then it will print out a unique row for every variation of pricing for that product_code. How do I get it to ignore those price variations and just add together every entry with that product code?
It is a little unclear what you are asking. My best guess is that you want the sum of the monthly base charge:
SELECT pc.product_code,
COUNT(*) as count,
sum(o.monthly_base_charge) as "Monthly Fee"
FROM orders o join
product_catalog pc
on pc.product_catalog_id = o.product_catalog_id
GROUP BY pc.product_code
ORDER BY count DESC;
I'm not sure if this is exactly what you want. What happens if you have two orders in the same month for the same product?
You may need to do something like this since SQL will not be able to know which monthly base charge to multiply by the count.
SELECT pc.product_code,
COUNT(*) as count,
(min(o.monthly_base_charge)*count(*)) as "Monthly Fee"
FROM orders o
join product_catalog pc on pc.product_catalog_id = o.product_catalog_id
GROUP BY pc.product_code
ORDER BY count DESC;
Or you will need to add o.monthly_base_charge to the group by in order for sql to know how to determine the count()
GROUP BY pc.product_code, o.monthly_base_charge