Add condition to sub select in query - database

I have this query
SELECT DISTINCT
u.email,
(
SELECT
count(DISTINCT o.id)
FROM
orders o
INNER JOIN cart_dates cd ON cd.order_id = o.id
WHERE
u.id = o.user_id
) as count
FROM
users u
How can I get rows only when count is, for example, < 20?

you can use group by and having clause.
select u.email
from users u
inner join orders o on o.user_Id = u.id
inner join card_dates cd on cd.order_id = o.id
group by u.email
having count(distinct o.id) < 20

Related

Add condition to two sub selects in query

I have this query.
SELECT DISTINCT
u.email,
(
SELECT
count(DISTINCT o.id)
FROM
orders o
INNER JOIN cart_dates cd ON cd.order_id = o.id
WHERE
u.id = o.user_id
) as total,
(
SELECT
count(DISTINCT o.id)
FROM
orders o
INNER JOIN cart_dates cd ON cd.order_id = o.id AND o.pre_order = TRUE
WHERE
u.id = o.user_id
) as count
FROM
users u
How can I get rows where for example, count > (total / 2)?
I am only assumming to answer this question.
SELECT
u.email
FROM
users u
INNER JOIN cart_dates cd ON cd.order_id = o.id
GROUP BY
u.email
HAVING
COUNT(DISTINCT Case when o.pre_order = TRUE then o.id else null end) >
(COUNT(DISTINCT o.id)/2)
I tried to making it more simpler.

T-SQL query not grouping results in output

I have the follwoing query embedded in a stored procedure
select u.UserName, s.Name, count(i.id) as NumberAccounts, sum(i.total) as CCTotal
from invoice i
inner join visit v on v.id = i.id
inner join branch b on b.id = v.branchid
inner join practice p on p.id = b.practiceid
inner join visitscheme vs on vs.id = v.id
inner join [plan] pl on pl.id = vs.planid
inner join scheme s on s.id = pl.schemeid
inner join creditcontrol cc on cc.SchemeId = s.id
inner join [user] u on u.id = cc.userid
where p.APIKey = #pracId
and (u.id = #CCid OR #CCId = '999999')
and (s.id = #SchemeId or #SchemeId = 999999)
group by u.UserName, s.Name
order by u.username
When I run it instead of result being grouped by username and scheme I get the following
UserName Name NumberAccounts CCTotal
chanel BANKMED 9954 11882514.19
ciske BANKMED 9954 11882514.19
Estee BANKMED 9954 11882514.19
Feroza BANKMED 9954 11882514.19
No grouping applied, the same values in each. Anyone know where I am going wrong?
Thanks
just write like this....
select u.UserName, s.Name, count(i.id) as NumberAccounts, sum(i.total) as CCTotal
from invoice i
inner join visit v on v.id = i.id
inner join branch b on b.id = v.branchid
inner join practice p on p.id = b.practiceid and p.APIKey = #pracId
inner join visitscheme vs on vs.id = v.id
inner join [plan] pl on pl.id = vs.planid
inner join scheme s on s.id = pl.schemeid and (s.id = #SchemeId or #SchemeId = 999999)
inner join creditcontrol cc on cc.SchemeId = s.id
inner join [user] u on u.id = cc.userid and (u.id = #CCid OR #CCId = '999999')
group by u.UserName, s.Name
order by u.username
assuming that your joins are correct

Get Max(id) from one to many table

I know this question was asked many times but I was tring and trying without success
I have one to many relationship between two tables and some more inner-joins to get more data.
Here is my query:
SELECT
ShopOffer.OfferID,
ShopOffer.OfferMessage,
Shop.ID,
Shop.Name,
Shop.Phone,
[User].Name,
[User].UserID,
ShopOfferStatus.Name AS StatusName,
BlockedShopInUser.IsBlocked
FROM
ShopOffer
INNER JOIN ShopOfferStatus ON ShopOffer.ShopOfferStatusID = ShopOfferStatus.ShopOfferStatusID
INNER JOIN Shop ON ShopOffer.ShopID = Shop.ShopID
INNER JOIN UserRequest ON ShopOffer.UserRequestID = UserRequest.UserRequestID
INNER JOIN [User] ON UserRequest.UserID = [User].UserID
INNER JOIN BlockedShopInUser ON Shop.ShopID = BlockedShopInUser.ShopID AND [User].UserID = BlockedShopInUser.UserID
Each shop can create many offers. In that query I would like to get only the last offer for each shop.
Thanks.
Here is a way:
;WITH LastShopOffer AS
(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY ShopID ORDER BY OfferID DESC)
FROM ShopOffer
)
SELECT
SO.OfferID,
SO.OfferMessage,
S.ID,
S.Name,
S.Phone,
U.Name,
U.UserID,
SOS.Name AS StatusName,
B.IsBlocked
FROM ( SELECT *
FROM LastShopOffer
WHERE RN = 1) SO
INNER JOIN ShopOfferStatus SOS
ON SO.ShopOfferStatusID = SOS.ShopOfferStatusID
INNER JOIN Shop S
ON SO.ShopID = S.ShopID
INNER JOIN UserRequest UR
ON SO.UserRequestID = UR.UserRequestID
INNER JOIN [User] U
ON UR.UserID = U.UserID
INNER JOIN BlockedShopInUser B
ON S.ShopID = B.ShopID
AND U.UserID = B.UserID;
I think you have to start with Shop and then perform a CROSS APPLY on the TOP 1 record from ShopOffer:
SELECT
ShopOffer.OfferID,
ShopOffer.OfferMessage,
Shop.ID,
Shop.Name,
Shop.Phone,
[User].Name,
[User].UserID,
ShopOfferStatus.Name AS StatusName,
BlockedShopInUser.IsBlocked
FROM Shop
CROSS APPLY (
SELECT TOP 1 OfferID, OfferMessage, ShopOfferStatusID, UserRequestID
FROM ShopOffer AS s
WHERE s.ShopID = Shop.ShopID
ORDER BY s.OfferID DESC
) ShopOffer
INNER JOIN ShopOfferStatus ON ShopOffer.ShopOfferStatusID = ShopOfferStatus.ShopOfferStatusID
INNER JOIN UserRequest ON ShopOffer.UserRequestID = UserRequest.UserRequestID
INNER JOIN [User] ON UserRequest.UserID = [User].UserID
INNER JOIN BlockedShopInUser ON Shop.ShopID = BlockedShopInUser.ShopID AND [User].UserID = BlockedShopInUser.UserID

sql server 2008, how to get rid of duplications when inner join 3 tables

here's my query. when I inner join 2 tables, there's no problem.
SELECT S.* ,
U.Avatar ,
U.Displayname ,
ROW_NUMBER() OVER ( ORDER BY S.Id DESC ) rownum
FROM dbo.Smoothie AS S
INNER JOIN dbo.[User] AS U ON S.UserId = U.Id
WHERE S.IsPublic = 1
AND S.Status = 3
AND S.UserId = 2
then, I added another inner join. now, I got alot duplications.
SELECT S.* ,
U.Avatar ,
U.Displayname,
ROW_NUMBER() OVER ( ORDER BY S.Id DESC ) rownum
FROM dbo.Smoothie AS S
INNER JOIN dbo.[User] AS U ON S.UserId = U.Id
INNER JOIN dbo.Favorite AS F ON U.Id = F.UserId
WHERE S.IsPublic = 1
AND S.Status = 3
AND F.UserId = 2
one solutions is to use distinct. however, I have to comment out row_number, i need that row_number to do paging. is there another way to get rid of duplication?
SELECT DISTINCT S.* ,
U.Avatar ,
U.Displayname
-- ROW_NUMBER() OVER ( ORDER BY S.Id DESC ) rownum
FROM dbo.Smoothie AS S
INNER JOIN dbo.[User] AS U ON S.UserId = U.Id
INNER JOIN dbo.Favorite AS F ON U.Id = F.UserId
WHERE S.IsPublic = 1
AND S.Status = 3
AND F.UserId = 2
Why not use the query you have, without the row_number as a subquery, then add the row number back later:
SELECT *,
ROW_NUMBER() OVER ( ORDER BY subQuery.Id DESC ) rownum
FROM (
SELECT DISTINCT S.* ,
U.Avatar ,
U.Displayname
FROM dbo.Smoothie AS S
INNER JOIN dbo.[User] AS U ON S.UserId = U.Id
INNER JOIN dbo.Favorite AS F ON U.Id = F.UserId
WHERE S.IsPublic = 1
AND S.Status = 3
AND F.UserId = 2
) AS subQuery
Dense_Rank would also do the job with the your otherwise unmodified query.

multiple count in a sql query

i need a report from a database where i need the final result like
Number of Male, Number of Female, showing against city and finally against State.
I started off with something like.
SELECT p.StateName, d.CityName,
count(api.Gender) as Gender
FROM dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by p.StateName, d.CityName
when i do this
SELECT p.StateName, d.CityName,
count(api.Gender = 'Male) as Male,
count(api.Gender = 'Female) as Female,
FROM dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by p.StateName, d.CityName
it give's me error.
incorrect syntax near =.
i also tried with select statement
COUNT(select api.Gender from api where api.Gender ='Male') as Male,
But it is also not working.
...
Any idea?
SELECT
p.StateName, d.CityName,
sum(case when Gender ='Male' then 1 else 0 end ) as Male_count,
sum(case when Gender ='Female' then 1 else 0 end ) as Female_count
FROM
dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by
p.StateName, d.CityName
You could try the PIVOT function if you are using SQL Server 2005 or later:
WITH CTE AS
( SELECT p.StateName,
d.CityName,
api.Gender
FROM dbo.Application_Personal_information as api
INNER JOIN dbo.state as p
ON api.State = p.ID
INNER JOIN dbo.City as d
ON api.City= d.ID
)
SELECT *
FROM CTE
PIVOT
( COUNT(Gender)
FOR Gender IN ([Male], [Female])
) pvt

Resources