T-SQL (Azure) table gives double results - sql

I am trying to get a list of all the id_user and the amount of creditRecieved and the amount of creditUsed, I actually would like to add a third option that mentions the left over if any. If creditReceived is bigger as creditUsed. But the first part now doubles the outputs so I started following an explanation here on StackOverflow, but I can't get it to work.
SELECT
dbo.UserPurchase.CreditUsed,
dbo.UserCredit.CreditRecieved
FROM
(
SELECT SUM(dbo.UserPurchase.creditUsed) AS CreditUsed
FROM dbo.UserPurchase
)
dbo.UserPurchase LEFT JOIN
(
SELECT SUM(dbo.UserCredit.creditRecieved) AS CreditRecieved
FROM dbo.UserCredit
)
dbo.UserCredit ON dbo.UserPurchase.id_user = dbo.UserCredit.id_user
The data comes from these two tables
TABLE dbo.UserCredit
id id_user creditRecieved PurchasePrice
----------- ----------- -------------- -------------
1 1 150 750
2 1 25 100
3 2 65 15
TABLE dbo.UserPurchase
id id_user creditUsed date
----------- ----------- ----------- -----------
1 1 175 NULL
2 2 3 NULL
3 2 2 NULL
I would like to have the following result
id_user CreditRecieved CreditUsed CreditLeftOver
----------- -------------- ----------- --------------
1 175 175 0
2 65 5 60

Try querying each table separately:
SELECT users.id_user, coalesce(credit.received, 0) received,
coalesce(purchase.used, 0) Used, coalesce(credit.received, 0) - coalesce(purchase.used, 0) LeftOver, coalesce(purchase.purchaseCount, 0) purchaseCount
FROM
(
select distinct id_user from dbo.UserCredit
union
select distinct id_user from dbo.UserPurchase
) users
left outer join
(
select id_user, sum(creditRecieved) received from dbo.UserCredit group by id_user
) credit
on users.id_user = credit.id_user
left outer join
(
select id_user, sum(creditUsed) used, count(1) purchaseCount from dbo.UserPurchase group by id_user
) purchase
on users.id_user = purchase.id_user
Please note that there is a typo in CreditRecieved. It should be CreditReceived.

If I understand you correctly, you want the creditUsed and creditRecieved (typo on your end?) summed up by id_user? This would be the query:
SELECT p.id_user, SUM(p.creditUsed), SUM(u.creditRecieved)
FROM dbo.UserCredit u
LEFT JOIN dbo.UserPurchase p ON p.id_user = u.id_user
GROUP BY p.id_user

You can use this query
SELECT
C.id_user,
C.CreditRecieved,
P.CreditUsed,
C.CreditRecieved - P.CreditUsed CreditLeftOver
FROM
(SELECT id_user, SUM(creditRecieved) CreditRecieved FROM UserCredit GROUP BY id_user) C
LEFT JOIN
(SELECT id_user, SUM(creditUsed) CreditUsed FROM UserPurchase GROUP BY id_user) P ON C.id_user = P.id_user

Related

Min and max auto Id column plus other columns from the same table

I need to retrieve data from a table relative to 3 columns i.e. max and min Id for every unique reservation_Id and rnoid pair.
This is what I have tried:
SELECT
R1.*,
R2.Id, R2.Res_Id, R2.rNoid
FROM
dbo.Res_Id R1
LEFT OUTER JOIN
dbo.Res_Id R2 ON R2.rNoid = R1.rNoid
AND (R2.Id > R1.Id --min
OR (R2.Id = R1.Id
AND r2.Res_Id <> r1.Res_Id)
)
-- AND R2.rNoid <> R1.rNoid
WHERE
R2.id IS NULL
ORDER BY
R1.Id
Results:
id Res_Id, rNoid, xxx_x, yyy_x, user_id
-------------------------------------------
1 1 33 5 null 1
2 3 44 0 3 1
3 13 22 0 null 1
4 1 22 2 5 2
5 3 5 0 5 2
6 3 77 1 3 2
I am getting some unique pairs skipped.
You may try this. This will create min(id) under cte section and max(id) under ct section. After that you may easily get the inner join on Res_Id and
rNoid to get your records.
; with cte as (
SELECT r.Res_Id, r.rNoid, MIN(r.id) as MinId
FROM dbo.Res_Id R1
GROUP BY r.Res_Id, r.rNoid
),
ct as (
SELECT r.Res_Id, r.rNoid, MAX(r.id) as MaxId
FROM dbo.Res_Id R1
GROUP BY r.Res_Id, r.rNoid
)
SELECT C.Res_Id, C.rNoid, MinId, MaxId FROM CTE AS C INNER JOIN CT AS CT
ON C.Res_Id = CT.Res_Id AND C.rNoid = CT.rNoid
max and min Id for every unique reservation_Id and rnoid pair.
You seem to want a simple aggregation query:
SELECT r.Res_Id, r.rNoid, MIN(r.id), MAX(r.id)
FROM dbo.Res_Id R1
GROUP BY r.Res_Id, r.rNoid;

sql table using sum

I would like a result of
ID received total
2 25 25
from ItemReceived table
ID item received
2 1 5
2 2 2
2 1 10
2 2 8
and ItemsToReceive table
ID item quantity
2 1 15
2 2 10
Is there a way to get this result?
I used this code:
SELECT sum(ItemsToReceive.quantity), SUM( ItemReceived.received)
FROM ItemsToReceive
INNER JOIN ItemReceived ON ItemReceived.ID = ItemsToReceive.ID
GROUP BY poitems.poid
I got a wrong result making received to 50...
Can anyone help me?
Try this
select t1.Id,t1.quantity, t2.received from
(
SELECT ID,sum(quantity) quantity from ItemsToReceive group by id
) as t1 inner join
(
SELECT ID,SUM(received) as received from ItemReceived group by id
) as t2 on t1.id=t2.id
This might help
;WITH quantity AS (
SELECT sum(ItemsToReceive.quantity) As TotQuant
,ItemsToReceive.id AS id
FROM ItemsToReceive
GROUP BY ItemsToReceive.id
), Prod As (
SELECT SUM( ItemReceived.received) As TotRec
,ItemReceived.ID As Id
FROM ItemReceived
GROUP BY ItemReceived.ID
)
SELECT
q.Id
,p.TotRec As Received
,q.TotQuant As Quantity
FROM quantity q
INNER JOIN Prod p on p.Id = q.id
select ID , sum(received) , sum(quantity) from ItemReceived left join ItemsToReceive on (ItemReceived.ID = ItemsToReceive.ID and ItemReceived.item = ItemsToReceive.item) group by ID

left join without duplicate values using MIN()

I have a table_1:
id custno
1 1
2 2
3 3
and a table_2:
id custno qty descr
1 1 10 a
2 1 7 b
3 2 4 c
4 3 7 d
5 1 5 e
6 1 5 f
When I run this query to show the minimum order quantities from every customer:
SELECT DISTINCT table_1.custno,table_2.qty,table_2.descr
FROM table_1
LEFT OUTER JOIN table_2
ON table_1.custno = table_2.custno AND qty = (SELECT MIN(qty) FROM table_2
WHERE table_2.custno = table_1.custno )
Then I get this result:
custno qty descr
1 5 e
1 5 f
2 4 c
3 7 d
Customer 1 appears twice each time with the same minimum qty (& a different description) but I only want to see customer 1 appear once. I don't care if that is the record with 'e' as a description or 'f' as a description.
First of all... I'm not sure why you need to include table_1 in the queries to begin with:
select custno, min(qty) as min_qty
from table_2
group by custno;
But just in case there is other information that you need that wasn't included in the question:
select table_1.custno, ifnull(min(qty),0) as min_qty
from table_1
left outer join table_2
on table_1.custno = table_2.custno
group by table_1.custno;
"Generic" SQL way:
SELECT table_1.custno,table_2.qty,table_2.descr
FROM table_1, table_2
WHERE table_2.id = (SELECT TOP 1 id
FROM table_2
WHERE custno = table_1.custno
ORDER BY qty )
SQL 2008 way (probably faster):
SELECT custno, qty, descr
FROM
(SELECT
custno,
qty,
descr,
ROW_NUMBER() OVER (PARTITION BY custno ORDER BY qty) RowNum
FROM table_2
) A
WHERE RowNum = 1
If you use SQL-Server you could use ROW_NUMBER and a CTE:
WITH CTE AS
(
SELECT table_1.custno,table_2.qty,table_2.descr,
RN = ROW_NUMBER() OVER ( PARTITION BY table_1.custno
Order By table_2.qty ASC)
FROM table_1
LEFT OUTER JOIN table_2
ON table_1.custno = table_2.custno
)
SELECT custno, qty,descr
FROM CTE
WHERE RN = 1
Demolink

MS Access SQL Query - Joining 3 Tables to receive Total Order Price

I would like to know the total price for a specific order ID. The information is contained in these tables:
Order_line_t
Order_ID Product_ID Quantity
-------- ---------- --------
1006 4 1
1006 5 2
1006 7 2
Uses_t
Product_ID Material_ID Footage
---------- ----------- -------
4 16 20
5 15 13
7 10 16
Raw_Materials_t
Material_ID Unit_Price
----------- ----------
16 05.70
15 16.72
10 15.55
The total cost is computed by
Multiplying SUM ( Order_line_t.Quantity * Uses_t.Footage * Raw_Materials_t.Unit_Price) AS Total
My current query only returns an error:
SELECT Order_line_t.Order_ID, Order_line_t.Product_ID, Uses_t.Product_ID ,Uses_t.Footage ,
SUM ( Order_line_t.Quantity * Uses_t.Footage * Raw_Materials_t.Unit_Price) AS Total
FROM Order_line_t, Uses_t , Raw_Materials_t
WHERE Order_line_t.Order_ID = 1006;
Help appreciated! How exactly do I JOIN these tables? What am i missing?
Firstly you were missing the actual joins between the tables, and secondly you were missing your group by
SELECT Order_line_t.Order_ID,
Order_line_t.Product_ID,
Uses_t.Product_ID ,
Uses_t.Footage ,
SUM ( Order_line_t.Quantity * Uses_t.Footage * Raw_Materials_t.Unit_Price) AS Total
FROM Order_line_t INNER JOIN
Uses_t ON Order_line_t.Product_ID = Uses_t.Product_ID INNER JOIN
Raw_Materials_t ON Uses_t.Material_ID = Raw_Materials_t.Material_ID
WHERE Order_line_t.Order_ID = 1006;
GROUP BY Order_line_t.Order_ID,
Order_line_t.Product_ID,
Uses_t.Product_ID ,
Uses_t.Footage
EDIT
Try this
SELECT Order_line_t.Order_ID,
Order_line_t.Product_ID,
Uses_t.Product_ID,
Uses_t.Footage,
Sum([Order_line_t].[Quantity]*[Uses_t].[Footage]*[Raw_Materials_t].[Unit_Price]) AS Total
FROM (Order_line_t INNER JOIN
Uses_t ON Order_line_t.Product_ID = Uses_t.Product_ID) INNER JOIN
Raw_Materials_t ON Uses_t.Material_ID = Raw_Materials_t.Material_ID
GROUP BY Order_line_t.Order_ID,
Order_line_t.Product_ID,
Uses_t.Product_ID,
Uses_t.Footage;
EDIT
Total by ORDER ID
SELECT Order_line_t.Order_ID,
Sum([Order_line_t].[Quantity]*[Uses_t].[Footage]*[Raw_Materials_t].[Unit_Price]) AS Total
FROM (Order_line_t INNER JOIN
Uses_t ON Order_line_t.Product_ID = Uses_t.Product_ID) INNER JOIN
Raw_Materials_t ON Uses_t.Material_ID = Raw_Materials_t.Material_ID
GROUP BY Order_line_t.Order_ID;
I think you need to compute the cost for each row, then sum the entire order. Something like:
select
Order_ID, sum(RowCost) as OrderCost
from (
select
o.Order_ID, o.Product_ID, o.Quantity,
u.Material_ID, u.Footage,
r.Unit_Price,
(o.Quantity * u.Footage * r.UnitPrice) as RowCost
from
order_line_t o INNER JOIN
uses_t u on o.Product_ID = u.Product_ID INNER JOIN
Raw_materials_t r on u.Material_ID = r.Material_ID
where
o.Order_ID = 1006
) z
group by
Order_ID

LEFT JOIN in 2 table

Why doesn't this query execute correctly?
SELECT pr.ProjectNumber,
SUM(ma.TotalAmount) As CostOfMaterials,
SUM(ot.TotalAmount) AS CostOfOthers
FROM [dbo].[tblProject] AS pr
LEFT JOIN [dbo].[tblCostOfMaterials] AS ma ON pr.ProjectNumber=ma.ProjectNumber
LEFT JOIN [dbo].[tblCostOfOthers] AS ot ON pr.ProjectNumber=ot.ProjectNumber
GROUP BY pr.ProjectNumber
I assume that you mean that because each table has multiple rows for a particular project number you count the same values multiple times. To avoid this you can use
;WITH ma
AS (select ProjectNumber,
SUM(TotalAmount) as CostOfMaterials
FROM [dbo].[tblCostOfMaterials]
GROUP BY ProjectNumber),
ot
AS (select ProjectNumber,
SUM(TotalAmount) as CostOfOthers
FROM [dbo].[tblCostOfOthers]
GROUP BY ProjectNumber)
SELECT pr.ProjectNumber,
CostOfMaterials,
CostOfOthers
FROM [dbo].[tblProject] AS pr
LEFT JOIN ma
ON pr.ProjectNumber = ma.ProjectNumber
LEFT JOIN ot
ON pr.ProjectNumber = ot.ProjectNumber
The reason why you get that behaviour is because you are getting mini Cartesian joins
WITH tblProject (ProjectNumber) AS
(
SELECT 1
),tblCostOfMaterials(ProjectNumber, TotalAmount) AS
(
SELECT 1,101 UNION ALL
SELECT 1,201 UNION ALL
SELECT 1,301
),
tblCostOfOthers(ProjectNumber, TotalAmount) AS
(
SELECT 1,100 UNION ALL
SELECT 1,200
)
SELECT *
FROM [tblProject] AS pr
LEFT JOIN [tblCostOfMaterials] AS ma ON pr.ProjectNumber=ma.ProjectNumber
LEFT JOIN [tblCostOfOthers] AS ot ON pr.ProjectNumber=ot.ProjectNumber
Returns
ProjectNumber ProjectNumber TotalAmount ProjectNumber TotalAmount
------------- ------------- ----------- ------------- -----------
1 1 101 1 100
1 1 101 1 200
1 1 201 1 100
1 1 201 1 200
1 1 301 1 100
1 1 301 1 200
You can see that the values are duplicated by the number of matching rows in the other table so the SUM will be incorrect.