Select Distinct Sum SQL Server - sql-server

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

Related

How can i select the highest bid for every card?

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;

How to get a hierarchical category products from top to down in sql

I keep product categories with parentid logic. I need to get all products under a category, but from top to down hierarchy. For example I have these tables:
ProductCategories
id CategoryID ProductID
1 4 1
2 5 2
3 6 3
4 8 4
5 8 5
6 9 5
7 9 2
Categories
ID CategoryName ParentID
1 Kids NULL
2 Accesories 1
3 Shoes 2
4 Flat Shoes 3
5 Leather Sandals 4
6 Sneakers 3
7 Clothing 1
8 T-Shirts 7
9 Bestsellers 1
Products
ID ProductName
1 White Espadrilles
2 Tan Leather Sandals
3 Beige Sneakers
4 Linen T-Shirt
5 Cotton T-Shirt
I use below Sql recursive query:
with CTE as
(
select c.ID,c.ParentID,c.CategoryName,p.ProductName
from Categories c
join ProductCategories pc
on pc.CategoryID=c.ID
join Products p
on pc.ProductID=p.ID
where c.ID = 5 --start id
union all
select ce.ID,ce.ParentID,ce.CategoryName,p.ProductName
from Categories ce
join ProductCategories pc
on pc.CategoryID=ce.ID
join Products p
on pc.ProductID=p.ID
join CTE
on ce.ID=CTE.ParentID
)
select * from CTE
Above query returns below result for a given CategoryID = 5 :
ID ParentID CategoryName ProductName
5 4 Leather Sandals Tan Leather Sandals
4 3 Flat Shoes White Espadrilles
if categoryID = 1 or 2 no record comes.
I dont have a product directly for Accesories category, but I have for it's child categories, so I should get all products under that, from top to down.
How can I do this?
You don't say which database you are using so I will give you a generic solution.
You can use a recursive CTE to produce a list of categories that include the starting one, plus all its children (in multiple levels). Then simple joins will do the rest, as you have already tried.
Here's an example. Tweak as necessary for your specific database:
with
categories_subtree as (
select id, categoryname, parentid
from categories
where id = 5 -- starting category
union all
select c.id, c.categoryname, c.parentid
from categories_subtree s
join categories c on c.parentid = s.id
)
select
p.id,
c.parentid
c.categoryname,
p.productname
from categories_subtree c
join productcategories pc on pc.categoryid = c.id
join products p on p.id = pc.productid

How to get category count using group by in sql server?

Hi i am create one query for get category count in which some period of time date. in my database i have 3 table first is category , subcategory , subcategoryfollow. now i want to who user follow sub category then i want to count for category. for ex user A follow 3 sub category for category 1 then user B follow same 3 sub category for category 1 then i want category 1 for count is getting 2 like this want result in the query but don't getting this type result.
Here is my query =>
select count(*) as Count,categroyName from categroy s inner join
(
select SS.categroyId from subcategory ss
inner join
(
select count(*) as count,subcategoryId from subcategoryfollow SSS
WHERE SSS.IsFollowed = 1 and CAST(SSS.InsertDateTime as date) >= CAST('2017-07-21' as date)
AND CAST(SSS.InsertDateTime as date) <= CAST('2017-07-22' as date)
group by SSS.subcategoryId,SSS.UserId
) as tab on tab.subcategoryId = ss.subcategoryId group by SS.subcategoryId
) as res on res.categroyId = s.categroyId where s.IsDeleted = 0
GROUP BY res.categroyId,categroyName
This is my current o/p =>
Count | categroyName
1 playing
1 Reading
This is my exepected o/p =>
Count | categroyName
2 playing
1 Reading
Table categroy data =>
categroyId | Name
1 playing
2 Reading
Table subcategory data =>
subcategoryId | categroyId | Name
1 1 cricket
2 1 football
3 1 wallyball
4 2 bibal
5 2 story
Table subcategoryfollow data =>
Id | UserId | subcategoryId | IsFollowed | InsertDateTime
1 10 1 1 2017-07-21 05:57:07.347
2 10 2 1 2017-07-21 05:56:02.347
3 10 3 1 2017-07-21 05:58:01.347
4 11 1 1 2017-07-21 05:59:08.347
5 11 2 1 2017-07-21 05:60:01.347
6 11 3 1 2017-07-21 05:61:06.347
7 13 4 1 2017-07-21 05:61:06.347
8 13 5 1 2017-07-21 05:61:06.347
this is my query and result. now in my table playing category store 3 sub category like cricket,football,wallyball now 2 user follow this 3 sub category so i want count 2 for the palying category. so please any one know how can do that.
I struggle to understand your question fully. Are you looking for something like below query.
SELECT c.Name, COUNT( DISTINCT UserId ) AS Cnt
FROM subcategory AS sc
INNER JOIN subcategoryfollow AS scf ON sc.subcategoryId = scf.subcategoryId
INNER JOIN categroy AS s ON sc.categroyId = s.categroyId
WHERE scf.IsFollowed = 1 and CAST(scf.InsertDateTime as date) >= CAST('2017-07-21' as date)
AND CAST(scf.InsertDateTime as date) <= CAST('2017-07-22' as date)
AND s.IsDeleted = 0
GROUP BY sc.categroyId, c.Name
According to your sample data and your expected result, try with the following SQL statement:
SELECT ucount, category FROM (
SELECT COUNT(F.userid) AS ucount,C.name AS category
FROM Category AS C
INNER JOIN SubCategory AS S ON C.categoryid = S.categoryid
INNER JOIN SubCategoryFollow AS F ON S.subcategoryid = F.subcategoryid
GROUP BY S.name,C.name) AS UserCount
GROUP BY ucount,category;

Select top N with joins

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

Selecting the Highest Seq Number by nested Joining

I would like to take biggest sequence number for each client Id (biggest sequence number will be calculated based on highest bank account balance).
This table has 100000 records.
Tables
ClientSeqTable T1
ClID SeqId
1 11
1 12
1 13
1 14
1 15
2 16
2 17
2 18
2 19
3 110
3 111
3 112
3 113
SeqBranchTable T2
SeqId BalID
11 1
12 2
13 3
14 4
15 5
16 6
17 7
18 8
19 9
110 10
111 11
112 12
113 13
Balancetable t3
BalID Balance
1 30000
2 26789
3 23456
4 12345
5 21234
6 12456
7 45632
8 23456
9 99999
10 12345
11 21234
12 12456
13 45632
Result would be
ClID SeqID Balance
1 1 30000
2 9 99999
3 4 45632
I have tried in this way but didn't work for me
SELECT RS.Investigationid,MAX(stt.sequenceid) 'SeqId', T.HighestBalance 'Balance'
FROM ClientSeqTable T1, SeqBranchTable T2, branbaltable t3,
( SELECT t1.clid ,MAX(T3.Balance) 'HighestBalance'
FROM ClientSeqTable T1, SeqBranchTable T2, branbaltable t3,
WHERE t1.seqid = T2.seqID
AND T2. balId= T3. balId
GROUP BY RS.Investigationid,stt.SequenceId
) T
WHERE T2.balId = T3.BalId
AND T1.SeqId = T2.SeqId
AND T3.HighestBalance = T2.balance
AND T1.clID = t.ClID
GROUP BY T1.ClID
With the above Query results are as below.
ClID SeqNu Bal
1 1 30000
1 2 30000
1 3 30000
1 4 30000
1 5 30000
2 3 99999
2 4 99999
2 1 99999
2 9 99999
3 2 45632
3 5 45632
3 3 45632
3 4 45632
If your able to use row_number function then should work:
select
*
from
(
select
t1.ClID, t1.SeqId, t3.Bal,
RowNumber = row_number() over (PARTITION BY t1.ClID order by t3.bal desc)
from
ClientSeqTable t1
inner join
SeqBranchTable t2 on t2.SeqId = t1.SeqId
inner join
Balancetable t3 on t3.BalID = t2.BalID
) t
where
t.RowNumber = 1
The important bit is row number partition by client id and then order by balance descending.
If you wanted to get your In-line on MAX you could do it this way
SELECT t1.ClID,
t1.SeqId,
t3.Balance
FROM ClientSeqTable t1
INNER JOIN SeqBranchTable t2
ON t2.SeqId = t1.SeqId
INNER JOIN Balancetable t3
ON t3.BalID = t2.BalID
INNER JOIN (SELECT Max(Balance) Bal,
t1.ClID
FROM ClientSeqTable t1
INNER JOIN SeqBranchTable t2
ON t2.SeqId = t1.SeqId
INNER JOIN Balancetable t3
ON t3.BalID = t2.BalID
GROUP BY t1.ClID) max_bal
ON t1.ClID = max_bal.ClID
AND t3.Balance = max_bal.bal
DEMO
But you should note this is not actually equivalent to using row_number (mouters solution). This may return multiple rows per ClID if there's a tie for max(balance). If you need that way of handling ties and you wanted to use a window function you could use RANK.

Resources