What we are trying to achieve is to retrieve the highest bid for every card from an auction. Users do not know who has bid how much thus allowing them to bid less or the same amount as other users. The issue we have right now is that we cannot find the right use of GROUP BY. For now we have the following queries:
-- This one does not order the records correctly
SELECT
DISTINCT ON ("auctionCardId") "auctionCardId",
auction_card_bid."userId",
auction_card_bid.id AS bid_id,
MAX(auction_card_bid.time),
MAX(auction_card_bid."bid")
FROM
auction_card_bid auction_card_bid
INNER JOIN auction_card ac ON ac.id = auction_card_bid."auctionCardId"
GROUP BY
auction_card_bid.id,
auction_card_bid."auctionCardId";
-- Orders the records correctly but it essentially returns all the records
SELECT
"auctionCardId",
auction_card_bid."userId",
auction_card_bid.id AS bid_id,
MAX(auction_card_bid.time),
MAX(auction_card_bid."bid")
FROM
auction_card_bid auction_card_bid
INNER JOIN auction_card ac on ac.id = auction_card_bid."auctionCardId"
GROUP BY
auction_card_bid.id,
auction_card_bid."auctionCardId"
ORDER BY
auction_card_bid.bid DESC,
auction_card_bid.time ASC;
We have the following database structure:
auction
id
start
end
1
2020-05-05
2020-05-06
auction_card
id
card_id
auction_id
min_bid
1
1
1
40
2
2
1
50
auction_card_bid
id
card_id
user_id
bid
time
1
1
1
10
2020-05-05 10:00
2
1
2
20
2020-05-05 10:05
3
1
3
20
2020-05-05 10:08
4
2
2
20
2020-05-05 10:10
5
2
3
40
2020-05-05 10:15
The ideal result would be something among the lines of:
user_id
auction_card_id
bid_id
bid
time
2
1
2
20
2020-05-05 10:05
3
2
5
40
2020-05-05 10:15
After a lot of trial and error, we finally found out how to achieve what we wanted.
SELECT DISTINCT ON ("auctionCardId") "auctionCardId" AS auction_card_id,
auction_card_bid.id bid_id,
value,
time,
"userId",
auction_card."auctionId"
FROM auction_card_bid auction_card_bid
JOIN auction_card auction_card ON auction_card_bid."auctionCardId" = auction_card.id
WHERE auction_card."auctionId" = 2
ORDER BY "auctionCardId", value DESC, time ASC;
Related
The first step is to join staff and customer together. The second step is to count the distinct product_id. My target is to add the total(sum) field under the result table.
Thanks.
staff
staff_ID Name cust_id
1 Tom 101
1 Tom 101
1 Tom 105
2 Peter 102
2 Peter 104
3 Billy 103
customer
cust_id product_id
101 A1
102 A2
103 A3
104 A4
105 A5
My work:
SELECT a.staff_name,COUNT(DISTINCT a.product_id)
FROM (SELECT distinct a.staff_id, a.staff_name, a.cust_id
FROM staff)a
LEFT JOIN customer b ON a.cust_id=b.cust_id
GROUPBY a.staff_name
What I want is to add the total column below the count.
Name count
Tom 2
Peter 2
Billy 1
Total 5
Update:
Regarding the "Total", as #MatBailie correctly pointed out in the comments:
The aggregate of multiple COUNT(DISTINCT) rows CAN NOT be guaranteed to be summable. If two staff members share the same product_id the summary value will be LESS THAN the sum of its members.
So for this sample data set:
db<>fiddle here
cust_id
product_id
101
A1
102
A2
103
A3
104
A4 <== Same product
105
A5
105
A4 <== Same product
Using GROUP BY ROLLUP yields a "Total" value of 5:
SELECT COALESCE(a.staff_name, 'Total') AS Staff_Name
, COUNT(DISTINCT b.product_id) AS [Count]
FROM staff a LEFT JOIN customer b ON a.cust_id=b.cust_id
GROUP BY ROLLUP (a.staff_name);
Results:
Staff_Name
Count
Billy
1
Peter
2
Tom
3
Total
5 **
Whereas calculating a simple sum of the totals, yields a "Total" value of 6. So just be aware of the difference.
Staff_Name
Count
Billy
1
Peter
2
Tom
3
Total
6 **
Original (Wrong Answer):
Can't remember where I saw this answer, but ... assuming Staff_Name is never null, you could use GROUP BY ROLLUP to obtain the total. That said calculating grand totals is usually more of a front-end job.
SELECT COALESCE(a.staff_name, 'Total') AS Staff_Name
, COUNT(DISTINCT b.product_id) AS [Count]
FROM staff a LEFT JOIN customer b ON a.cust_id=b.cust_id
GROUP BY ROLLUP (a.staff_name);
Try this one:
SELECT s.staff_name, COUNT(DISTINCT b.product_id), SUM(count) Total
FROM staff s
INNER JOIN customer b ON b.cust_id = s.cust_id
GROUP BY s.staff_name
PaymentID SupplyInvoiceID Date TotalBill BillPaidAmount Remaining Bill
1 1 05-04-2018 2,10,000 20,000 1,90,000
2 1 10-05-2018 2,10,000 60,000 1,30,000
3 1 13-06-2018 2,10,000 1,30,000 0
4 2 10-05-2018 80,000 40,000 40,000
5 2 13-06-2018 80,000 20,000 20,000
6 2 13-06-2018 80,000 20,000 0
The payment of each Bill is paid in installments in different dates as shown above. How to find the remaining Bill amount each time when the partial payment of each bill is made?
I used the following Query:
SELECT siph.SupplyPaymentID,si.SupplyInvoiceID,
siph.DateOfPayment,si.TotalBill, siph.BillPaidAmount,
si.TotalBill - SUM(siph.BillPaidAmount) over(order by siph.SupplyPaymentID asc) as RemainingBillAmount,
siph.PaymentMode
from SupplyInvoicePaymentHistory siph inner join
SupplyInvoice si
on siph.SupplyInvoiceID = si.SupplyInvoiceID
But it works fine for only bill payments of 1st SupplyInvoiceID. As i enter the bill payments of 2nd and onward SupplyInvoiceID, i gets the wrong result as follows:
PaymentID SupplyInvoiceID Date TotalBill BillPaidAmount Remaining Bill
1 1 05-04-2018 2,10,000 20,000 1,90,000
2 1 10-05-2018 2,10,000 60,000 1,30,000
3 1 13-06-2018 2,10,000 1,30,000 0
4 2 10-05-2018 80,000 40,000 -1,70,000
5 2 13-06-2018 80,000 20,000 -1,90,000
6 2 15-06-2018 80,000 20,000 -2,10,000
..please help to find the correct result as tabulated at the first para of the above question.
You need to add PARTITION BY clause to your sum() over () to make it a cumulative sum for each Invoice ID.
Add this to your RemainingBillAmount column:
... - SUM(...) over (partition by si.SupplyInvoiceID ...)
Entire query:
SELECT siph.SupplyPaymentID,si.SupplyInvoiceID,
siph.DateOfPayment,si.TotalBill, siph.BillPaidAmount,
si.TotalBill - SUM(siph.BillPaidAmount) over(partition by si.SupplyInvoiceID order by siph.SupplyPaymentID asc) as RemainingBillAmount,
siph.PaymentMode
from SupplyInvoicePaymentHistory siph inner join
SupplyInvoice si
on siph.SupplyInvoiceID = si.SupplyInvoiceID
I'm trying to figure it out how to put a column of max of another table into a view table!
so here is my tables:
TblProprtyDetails
id Property_id amount situation
1 1 152 true
2 1 545 false
3 2 5 false
4 2 87 true
TblExperties
id PropertyDetails_id ExpertiesDate ExpertiesPrice
1 1 2015-10-01 54
2 1 2015-11-15 546
3 2 2016-01-05 6895
4 2 2016-08-01 654
now I want to put Max of ExpertiesDate and sum of amount into a view in this structure:
id Property_id amount situation LastExpertiesDate
select
id ,Property_id,amount,situation,max(ExpertiesDate) as lastexpertisedate
from
TblProprtyDetails t1
join
TblExperties t2
on t1.id=t2.id
group by
id ,Property_id,amount,situation
You also can use cross apply
select
id ,Property_id,amount,situation,b.*
from
TblProprtyDetails t1
cross apply
(
select max(ExpertiesDate) as lastexpertisedate from table t2 where
t1.id=t2.id) b
I am looking to join 2 tables with top n results of other table as explained below.
OrderHeader
OH_Id OrderDate
----------------------
1 2014-06-01
2 2014-06-02
3 2014-06-03
4 2014-06-04
5 2014-06-05
OrderProducts
OP_Id OH_Id Quantity
------------------------------
1 1 1
2 1 2
3 2 1
4 3 3
5 4 4
6 4 1
7 4 2
8 5 2
9 5 1
I am expecting result something like this for top 3 orders (4 rows).
OH_Id OrderDate Op_Id Quantity
------------------------------------------------
1 2014-06-01 1 1
1 2014-06-01 2 2
2 2014-06-02 3 1
3 2014-06-03 4 3
Note: I am looking specifically to join 2 tables rather writing as SP or looped queries.
select top 3 o.oh_id, o.orderdate, oo.op_id, oo.quantity
from orderheader o
join orderproducts oo on o.oh_id = oo.oh_id
If you want the first 3 order numbers from OrderHeader with all corresponding rows from OrderProducts try this.
select o.oh_id
,o.orderdate
,oo.op_id
,oo.quantity
from (SELECT TOP 3 *
FROM orderheader
ORDER BY OH_ID --or Date etc...
) o
INNER JOIN orderproducts oo
on o.oh_id = oo.oh_id
I think your description is confusing. You don't want top 3 as that will return only 3 rows. You just want ids 1-3 from what it sounds like.
SELECT *
FROM OrderHeader a
JOIN OrderHeader b on a.oh_id = b.oh_id
WHERE a.oh_id <= 3
you have to use a sub query like this
SELECT * FROM OrderHeader
INNER JOIN OrderProducts ON OrderHeader.OH_Id = OrderProducts.OH_Id
WHERE OrderHeader.OH_Id IN (SELECT TOP 3 OH_Id FROM OrderHeader)
A test sql fiddle is here
hope this helps
I have a problem with the SUM(tblReview.GradePoint) I get 6 as result for GroupID Ballon because I have three products with GroupID Ballon, but I want the result to be 2 because there is only one review with that groupID in tblReview, how can I do that?
SELECT Product.GroupID,
max(Product.ProductID) as ProductID,
max (Product.BrandID) as BrandID,
max (Product.Year) as Year,
max (Product.Name) as Name,
max (tblBrand.BrandName)as BrandName,
SUM(tblReview.GradePoint) as GradePoint
FROM Product INNER JOIN
tblBrand ON Product.BrandID = tblBrand.BrandID LEFT OUTER JOIN
tblReview ON Product.GroupID = tblReview.GroupID
GROUP BY Product.GroupID
HAVING COUNT(distinct Product.GroupID) = 1
ORDER BY GradePoint DESC
Product
ProductID GroupID BrandID
--------------------------------------
1 Ballon 10
2 Ballon 10
3 Ballon 10
4 Ball 21
5 Ball 21
6 Chess 2
7 Chess 2
8 Hat 30
tblReview
ProductID GroupID GradePoint
------------------------------------------
2 Ballon 2
4 Ball 1
5 Ball 1
5 Ball 1
6 Chess -1
8 Hat 1
tblBrand
BrandID ProductID
-----------------------
10 1
10 2
10 3
21 4
21 5
2 6
2 7
30 8
Try this:
SELECT Product.GroupID,
max(Product.ProductID) as ProductID,
max (Product.BrandID) as BrandID,
max (Product.Year) as Year,
max (Product.Name) as Name,
max (tblBrand.BrandName)as BrandName,
max(tblReview.GradePoint) as GradePoint
FROM Product INNER JOIN
tblBrand ON Product.BrandID = tblBrand.BrandID LEFT OUTER JOIN
(SELECT GroupID, SUM(GradePoint) GradePoint FROM tblReview GROUP BY GroupID) tblReview ON Product.GroupID = tblReview.GroupID
GROUP BY Product.GroupID