Rows being multiplied by number of results - sql

SELECT s.SR_Service_RecID -- will have 1 result
, p.Description -- will have 8 results
, t.notes -- will have 5 results
FROM SR_Service s
LEFT JOIN IV_Product p
ON p.SR_Service_RecID = s.SR_Service_RecID
LEFT JOIN Time_Entry t
ON t.SR_Service_RecID = s.SR_Service_RecID
This query is multiplying p.Description by t.Notes for the total number of rows. Each p.Description is displaying 5 times against each individual t.notes.
Result set:
SR_RecID Description Notes
12345 Product 1 Note 1
12345 Product 1 Note 2
12345 Product 1 Note 3
12345 Product 1 Note 4
12345 Product 1 Note 5
12345 Product 2 Note 1
12345 Product 2 Note 2
12345 Product 2 Note 3
12345 Product 2 Note 4
12345 Product 2 Note 5
Etc..
I'm unsure how to resolve this one... any help would be appreciated.
[EDIT]:
As the results are correct how can you put this into an SSRS report to show only the correct amount of results as it will display all duplicated rows?
SR_RecID
12345
Description
Product 1
Product 2
Product 3
Product 4
Product 5
Product 6
Product 7
Product 8
Notes 1
Notes 2
Notes 3
Notes 4
Notes 5

If by "resolving" you mean how to only have 1 note for each SR_RecID and Description then you would need to select only 1 Notes for each by using Aggregate function (MAX, MIN, etc.).
Otherwise, as commented several times, your result is what to be expected.

Related

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.. :)

SQL/Microsoft Access

I am trying to figure out this problem but, it's already taking me a few days and I cant seem to solve it.
The questions demands:
Display a list of products (show ProductID and ProductDescription as the first two columns), the number of times each product has been ordered (the third column), and the total quantity each product has been ordered over all orders (the forth column).
The Database:
**Product_T** **OrderLine_T**
ProductID ProductDescription ProductID OrderedQuantity
1 End Table 1 2
2 Coffe Table 2 2
3 Computer Desk 4 1
4 Entertainment Center 3 5
5 Writers Desk 3 3
6 8-Drawer Desk 6 2
7 Dining Table 8 2
8 Computer Desk 4 4
4 1
5 2
7 2
1 3
2 2
3 3
8 3
4 2
7 3
8 10
Just a JOIN and GROUP BY
SELECT p.ProductID,
p.ProductDescription,
COUNT(*) AS time_ordered,
SUM(o.OrderedQuantity) AS qty_ordered
FROM Product_T as p
LEFT JOIN OrderLine_T AS o
ON p.ProductID = o.ProductID
GROUP BY p.ProductID,
p.ProductDescription;
Try this:
SELECT t1.ProductID,
t1.ProductDescription,
COALESCE(t2.num_times_ordered, 0) AS num_times_ordered,
COALESCE(t2.total_quantity, 0) AS total_quantity
FROM Product_T t1
LEFT JOIN
(
SELECT ProductID,
COUNT(*) AS num_times_ordered,
SUM(OrderedQuantity) AS total_quantity
FROM OrderLine-T
GROUP BY ProductID
) t2
ON t1.ProductID = t2.ProductID
The answer given by #GurV is more concise than this and works for this particular problem, but in general you would need to use a subquery to obtain stats from the OrderLine-T table, assuming that you wanted to include non-aggregate columns from Product_T in your report.

Multiply newly entered row with another column value and find Total Sum in SQL

I have 4 tables here, I need to multiply newly entered row value in a table with another row and find the total sum using CustomerId:
CustomerTable:
CustomerId Name EmailId
-------------------------
1 Paul r#r.com
2 John J#j.com
LoyaltyPointTable:
LoyaltyPointsId LoyaltyType Points
---------------------------------------
1 Registration 10
2 Loginstatus 1
3 Downloading 10
4 Redemming 1
5 Sharing 20
6 Refer 10
LoyaltyDetailsTable:
LoyaltyDetailsId LoyaltyPointsId CustomerId Dates
-------------------------------------------------
1 1 1 2015-01-22
2 2 1 2015-01-22
3 3 2 2015-01-22
4 3 1 2015-01-22
5 4 1 2015-01-22
6 4 1 2015-01-24
7 5 1 2015-01-24
This query works fine for the total sum for each LoyaltyType
SELECT
LoayaltyPointsTable.LoyaltyType,
COUNT(CustomerTable.CustomerId) AS UserActions,
SUM(LoayaltyPointsTable.Points) AS TotalPoints
FROM
LoayaltyPointsTable
JOIN
LoyaltyDetailsTable ON LoayaltyPointsTable.LoyaltyPointsId = LoyaltyDetailsTable.LoyaltyPointsId
JOIN
CustomerTable ON CustomerTable.CustomerId = LoyaltyDetailsTable.CustomerId
WHERE
CustomerTable.CustomerId = 1
GROUP BY
LoyaltyDetailsTable.CustomerId ,LoayaltyPointsTable.LoyaltyType
below RedeemPointsTable is created with relation to row redeeming in LoyaltyPointTable:
RedeemPointsTable:
RedeemPointsId CustomerId ShopName BillNo Amount
------------------------------------------------
1 1 Mall x 4757 100
3 1 Mall y SH43 50
4 1 Mall x 7743 10
6 1 Mall x s34a 60
What I am expecting is before calculating the total sum, I want column Amount sum (100+50+10+60) * 1 in Redeeming in LoyaltyPointTable to be added with total points for each CustomerId
Expected output
LoyaltyType UserActions TotalPoints
-------------------------------------
Downloading 1 10
Loginstatus 1 1
Redemming 4 (100+50+10+60)*1(here using Amount in RedeemPointsTable)
Refer 1 10
Registration 1 10
Sharing 1 20
User actions count is 4, it is based on the Amount he entered in RedeemPointsTable
Should I need to make changes in adding a foreign key column in RedeemPointsTable or can you point out my mistake?
Any help would be great.
This is the query which returns desired result:
SELECT
LoyaltyPointTable.LoyaltyType,
CASE
WHEN LoyaltyPointTable.LoyaltyPointsId=4 THEN (SELECT COUNT(amount) FROM RedeemPointsTable where CustomerId=1)
ELSE COUNT(CustomerTable.CustomerId)
END as UserActions,
CASE
WHEN LoyaltyPointTable.LoyaltyPointsId=4 THEN (SELECT SUM(amount) FROM RedeemPointsTable where CustomerId=1)*Points
ELSE SUM(LoyaltyPointTable.Points)
END as TotalPoints
FROM
LoyaltyPointTable
JOIN
LoyaltyDetailsTable ON LoyaltyPointTable.LoyaltyPointsId = LoyaltyDetailsTable.LoyaltyPointsId
JOIN
CustomerTable ON CustomerTable.CustomerId = LoyaltyDetailsTable.CustomerId
WHERE
CustomerTable.CustomerId = 1
GROUP BY
LoyaltyDetailsTable.CustomerId ,LoyaltyPointTable.LoyaltyType
You can check it here

Grouping a row based on field in a different table in oracle

I am working with these two tables for the past two days
parts_list table:
PART_ID VENDOR_ID LABEL
1 5 A
1 2 B
1 3 C
2 2 D
2 3 E
3 3 F
vendor_prsdnc table:
VENDOR_ID PRSCDNC
5 3
2 2
3 1
Can anybody please tell me how to retrieve the label of each part from the vendor with highest precedence? For example the part with id one is supplied by 3 vendors but we need the one from vendor with highest precedence ie 5. The expected result is:
PART_ID VENDOR_ID LABEL
1 5 A
2 2 D
3 3 F
[Vendor Id is not proportional with the precedence ]
I have this query
SELECT
SDS.PART_ID,
SDSIS.VENDOR_ID,
MAX(SDSIS.PRSCDNC)
FROM PARTS_LIST SDS,VENDOR_PRSDNC SDSIS
WHERE SDS.VENDOR_ID=SDSIS.VENDOR_ID
GROUP BY SDS.PART_ID,SDSIS.VENDOR_ID;
but it does not return the expected result.
Not tested ,but it should work i think
select part_id,vendor_id,label
from
(
select pl.part_id
,pl.vendor_id
,pl.label
,vp.prscdnc
,max(vp.prscdnc) over (partition by pl.part_id) mx
from part_list pl,vendor_prsdnc vp
where pl.vendor_id=vp.vendor_id
)
where prscdnc =mx;

Result set with multiplied rows into an SSRS report

I need to get this query into an SSRS report.
SELECT s.SR_Service_RecID -- will have 1 result
, p.Description -- will have 8 results
, t.notes -- will have 5 results
FROM SR_Service s
LEFT JOIN IV_Product p
ON p.SR_Service_RecID = s.SR_Service_RecID
LEFT JOIN Time_Entry t
ON t.SR_Service_RecID = s.SR_Service_RecID
This query is multiplying p.Description by t.Notes for the total number of rows as expected.
Result set:
SR_RecID Description Notes
12345 Product 1 Note 1
12345 Product 1 Note 2
12345 Product 1 Note 3
12345 Product 1 Note 4
12345 Product 1 Note 5
12345 Product 2 Note 1
12345 Product 2 Note 2
12345 Product 2 Note 3
12345 Product 2 Note 4
12345 Product 2 Note 5
Etc..
How can this be put into an SSRS report so it displays only the actual results, not the multiplied amounts?
SR_RecID
12345
Description
Product 1
Product 2
Product 3
Product 4
Product 5
Product 6
Product 7
Product 8
Notes 1
Notes 2
Notes 3
Notes 4
Notes 5
Do I need to rework the query or can this be done on the SSRS end of things?
Yes, you can achieve this by adding tablix:
and using 3 adjacent groups (grouped by each field) like follows:
You will get this result: