Selecting first record name from duplicate values - sql

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.

Related

Not contained in eaggregate function/ the GROUP BY AND max date does not show the latest date

I am stucked here and your help will be appreciated. Based on the code that you see below:
I have a sub query with some conditions. especifically, the following:
AND OwnedByTeamJ='C - O Review'
AND OwnedByTeamJ is null
I want to get the results from the subquery,
Do another select on them because all I want is the latest date listed the table. As you can see in the picture, I want to be able to extract row#3 which has the highest date and its own by the team which is null (I guess! since there is no value there).
Now the problems:
1-at first the code worked and I saw all the records! though, it didsn't pick the latest date
2- sudennly it stopped working and saw this error:
Column 'tt.IncidentID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
select
distinct max(LastModifiedDateTimeJ),
incidentID,
EffecRequestStatus,
OwnedByTeamJ
From (
select
EffecRequestStatus,
IncidentID,
LastModifiedDateTimeJ,
OwnedByTeamJ,
DetailsJ,
Status,
OwnedByTeam
from IncidentView
where
CAST(CreatedDateTime as DATE) >='05-01-2019'
AND JournalTypeName like '%Journal - Note%'
AND OwnedByTeamJ='C - O Review'
AND OwnedByTeamJ is null
group by
EffecRequestStatus,
IncidentID,
LastModifiedDateTimeJ,
OwnedByTeamJ,
DetailsJ,
Status,
OwnedByTeam
) as tt
where
tt. RequestStatus not in ('Submission','P-C submission','C Review')
A sample of data look like the following but my table has more columns than that is listed here:
1) These conditions should not coexist:
AND OwnedByTeamJ='C - O Review'
AND OwnedByTeamJ is null
...because these two things are never true at the same time, and you will get an empty result-set. I guess what you want is
AND (OwnedByTeamJ='C - O Review' or OwnedByTeamJ is null)
2) The error you mention does not seem to agree with the query you've shown us. Did you try to make another group by externally?
3) It doesn't make sense to use distinct together with any aggregation function like max,sum, count etc.
4) As long as you have included EffecRequestStatus within the group by, you will get 3 rows, not 1, because all 3 rows have a different value for EffecRequestStatus. You will have to remove it from the group by, and therefore from the select as well, if you only want to see one row.
Try this, if you want to have a not empty result:
AND (OwnedByTeamJ='C - O Review'
OR OwnedByTeamJ is null)

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.

How to retrieve those records whose data is same

I have this query below,
SELECT DISTINCT
OD.[Customer]
,OD.[OrderNumber] 'Order#'
,OD.[Shipper]
,OD.[Product]
,OD.[Dock] 'Dock/Track'
,OD.[Lines] 'Berth/Position'
,[TAMS].[fnc_GetDelayCountByOrderNumber](OD.OrderNumber) 'Delays'
,OD.[ScheduledArrival] 'Sched .Arrival'
,OD.ActiveCheckPointStatus 'Active CheckPoint'
,OD.[CheckPointStatus] 'CheckPoint Status'
,OD.[ContractNumber]
,OD.[Direction]
,OD.[Volume]
,OD.[PreviousCheckPointStatus]
,OD.[CheckPointType]
,OD.[SourceContainer]
,OD.[DestinationContainer]
,OD.[UnitsOfMeasure]
,OD.ConveyanceID
,OD.TripId
,OD.NumberOfConveyance
,OD.Volume
FROM TAMS.OrderDetail OD
WHERE OrderNumber= 8394
This query returns 4 records
This query has same ordernumber (8394), same conveyanceid(178047), same tripid(211583). But only different is product (AGGREGATE, LIMESTONE)
So instead of showing four records how can i show like just two records of different products (Aggregate, Limestone).
It should look like
In your query, you are requesting DISTINCT VOLUME along with everything else, if you are going to keep the distinct in your query then you will need to remove the volume column because as long as those volumes are different the query will return those four distinct rows. Only other option would be to group by the customer, order, etc and select the max/min/avg volume, but I can't tell by your question whether or not you need to have the volume returned. I noticed VOLUME isn't included in your second screenshot, so maybe you don't need it?

Select inside select

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;

Oracle Group by issue

I have the below query. The problem is the last column productdesc is returning two records and the query fails because of distinct. Now i need to add one more column in where clause of the select query so that it returns one record. The issue is that the column i need
to add should not be a part of group by clause.
SELECT product_billing_id,
billing_ele,
SUM(round(summary_net_amt_excl_gst/100)) gross,
(SELECT DISTINCT description
FROM RES.tariff_nt
WHERE product_billing_id = aa.product_billing_id
AND billing_ele = aa.billing_ele) productdescr
FROM bil.bill_sum aa
WHERE file_id = 38613 --1=1
AND line_type = 'D'
AND (product_billing_id, billing_ele) IN (SELECT DISTINCT
product_billing_id,
billing_ele
FROM bil.bill_l2 )
AND trans_type_desc <> 'Change'
GROUP BY product_billing_id, billing_ele
I want to modify the select statement to the below way by adding a new filter to the where clause so that it returns one record .
(SELECT DISTINCT description
FROM RRES.tariff_nt
WHERE product_billing_id = aa.product_billing_id
AND billing_ele = aa.billing_ele
AND (rate_structure_start_date <= TO_DATE(aa.p_effective_date,'yyyymmdd')
AND rate_structure_end_date > TO_DATE(aa.p_effective_date,'yyyymmdd'))
) productdescr
The aa.p_effective_date should not be a part of GROUP BY clause. How can I do it? Oracle is the Database.
So there are multiple RES.tariff records for a given product_billing_id/billing_ele, differentiated by the start/end dates
You want the description for the record that encompasses the 'p_effective_date' from bil.bill_sum. The kicker is that you can't (or don't want to) include that in the group by. That suggests you've got multiple rows in bil.bill_sum with different effective dates.
The issue is what do you want to happen if you are summarising up those multiple rows with different dates. Which of those dates do you want to use as the one to get the description.
If it doesn't matter, simply use MIN(aa.p_effective_date), or MAX.
Have you looked into the Oracle analytical functions. This is good link Analytical Functions by Example