Get Count in One to Many relation in sql - sql

here is the link of the related question Related question ,
Now i have a query which gives me the company name exactly as i want
QUERY
SELECT CASE WHEN COALESCE(b.totalCoupons, 0) > 3 THEN a.Name +'(Important) '
WHEN IsHighPriority = 1 THEN a.Name +'(High Priority) '
ELSE a.Name +''
END AS CompanyName
FROM Company a
LEFT JOIN
(
SELECT Name, COUNT(*) totalCoupons
FROM Company
GROUP BY Name
) b ON a.name = b.name
Now i want that In the scenario of (important) we are testing that if company have more then 3 coupons then add (Important) infront of Company name but i want to do that if
a company have more then 3 coupons where
RejectProcessed = 0 and ReviewVerify = 0 and isPublish = 0 and ForSupervisor = 0
then i want to add important infront of that particular company name . So , what should i do .
Please feel free to ask if you need any detail .
Thanks in advance

This query solved my problem
SELECT CASE WHEN COALESCE(b.totalCoupons, 0) > 3 THEN company.Name +' (Important) '
WHEN IsHighPriority = 1 THEN company.Name +' (High Priority) '
ELSE company.Name +''
END AS CompanyName , company.id as Companyid
FROM Company company
left JOIN
(
SELECT co.Name as coName, co.id as coid, COUNT(c.id) totalCoupons
FROM Company co, Coupon c
where c.CompanyId = co.id and c.RejectedProcessed = 1 and c.ReviewVerify = 0 and c.isPublish = 0 and c.ForSupervisor = 0
GROUP BY co.Name, co.id
) b ON company.id = b.coid

#user2193861, is Coupon present in left join with company table..?
LEFT JOIN
(
SELECT Name, COUNT(*) totalCoupons
FROM Coupon
GROUP BY Name
) b ON a.name = b.name

Use this..
SELECT CASE WHEN COALESCE(b.totalCoupons, 0) > 3 THEN a.Name +'(Important) '
WHEN IsHighPriority = 1 THEN a.Name +'(High Priority) '
ELSE a.Name +''
END AS CompanyName
FROM Company a
LEFT JOIN
(
SELECT Name, COUNT(*) totalCoupons
FROM Company C
WHERE
EXISTS(
select 1
from coupon P
where P.RejectProcessed = 0 and P.ReviewVerify = 0
and P.isPublish = 0 and P.ForSupervisor = 0
and P.CompanyName = C.Name
)
and in second query..
use WHERE P.RejectProcessed = 0 and P.ReviewVerify = 0
and P.isPublish = 0 and P.ForSupervisor = 0

Related

SQL Server query slow - how do optimize it?

I would like some help to optimize this query to be faster.
This query produces a view that latter will be showed in a table in a website.
This query is slow, and I am trying to make it faster.
The only thing I tried till now is to reduce the amount of columns I retrieve for the table.
This is the query:
SELECT TOP (100) PERCENT Id, MAX(BusinessTitle) AS BusinessTitle, MAX(ClientName) AS ClientName, MAX(ClientType) AS Type, MAX(CreatedWhen) AS CreatedWhen, MAX(CASE WHEN C.[CreatedBy] IS NULL
THEN 'Client' ELSE 'Admin' END) AS CreatedBy, CAST(MAX(CASE WHEN C.IsDisabled = 1 THEN 1 ELSE 0 END) AS BIT) AS IsDisabled, MAX(ReferenceSource) AS ReferenceSource, MAX(OtherReferenceSource)
AS OtherReferenceSource, MAX(Address) AS Address,
(SELECT MAX(T.FirstName + ' ' + T.LastName) AS Expr1
FROM dbo.ApplicationUsers AS A INNER JOIN
dbo.Therapists AS T ON A.UserName = MAX(C.ClientName) AND A.Id = T.ApplicationUserId) AS ClientAdmin,
(SELECT MAX(A.Email) AS Expr1
FROM dbo.ApplicationUsers AS A INNER JOIN
dbo.Therapists AS T ON A.UserName = MAX(C.ClientName) AND A.Id = T.ApplicationUserId) AS Email,
(SELECT MAX(Name) AS Expr1
FROM dbo.Cities AS CY
WHERE (Id = MAX(C.CityId))) AS City,
(SELECT COUNT(*) AS Expr1
FROM dbo.Patients AS P
WHERE (ClientId = C.Id)) AS TotalPatientCount,
(SELECT COUNT(*) AS Expr1
FROM dbo.Patients AS P
WHERE (ClientId = C.Id) AND (IsDeleted = 0) AND (IsDisabled = 0)) AS ActivePatientCount,
(SELECT MAX(CreatedWhen) AS Expr1
FROM dbo.Patients AS P
WHERE (ClientId = C.Id)) AS LastPatientAddition,
(SELECT COUNT(*) AS Expr1
FROM dbo.Treatments AS T
WHERE (ClientId = C.Id)) AS TotalTreatmentCount,
(SELECT MAX(CreatedWhen) AS Expr1
FROM dbo.Treatments AS T
WHERE (ClientId = C.Id)) AS LastTreatmentAddition,
(SELECT COUNT(*) AS Expr1
FROM dbo.Therapists AS T
WHERE (ClientId = C.Id)) AS TotalTherapistCount,
(SELECT COUNT(*) AS Expr1
FROM dbo.Therapists AS T INNER JOIN
dbo.ApplicationUsers AS A ON T.ClientId = C.Id AND T.ApplicationUserId = A.Id
WHERE (A.IsDeleted = 0) AND (A.IsDisabled = 0)) AS ActiveTherapistCount,
(SELECT MAX(A.CreatedWhen) AS Expr1
FROM dbo.Therapists AS T INNER JOIN
dbo.ApplicationUsers AS A ON T.ClientId = C.Id AND T.ApplicationUserId = A.Id) AS LastTherapistAddition,
(SELECT MAX(A.LastLoginDate) AS Expr1
FROM dbo.Therapists AS T INNER JOIN
dbo.ApplicationUsers AS A ON T.ClientId = C.Id AND T.ApplicationUserId = A.Id
WHERE (A.LastLoginDate IS NOT NULL)) AS TherapistLastLoginDate, CAST((CASE WHEN
((SELECT COUNT(S.[Id])
FROM [dbo].[ClientSubscriptions] AS S
WHERE ((S.[ClientId] = C.[Id]) AND (S.[IsDeleted] = 0) AND ((S.[SubscriptionEnd] IS NULL) OR
(S.[SubscriptionEnd] > GETDATE())))) > 0) THEN 1 ELSE 0 END) AS BIT) AS HasActiveSubscription,
(SELECT MAX(SubscriptionEnd) AS Expr1
FROM dbo.ClientSubscriptions AS S
WHERE (ClientId = C.Id) AND (IsDeleted = 0) AND (SubscriptionEnd IS NULL OR
SubscriptionEnd > GETDATE())) AS LastValidSubscriptionEnd, CAST((CASE WHEN
((SELECT COUNT(S.[Id])
FROM [dbo].[ClientSubscriptions] AS S
WHERE ((S.[ClientId] = C.[Id]) AND (S.[IsDeleted] = 0) AND ((S.[SubscriptionEnd] IS NULL) OR
(S.[SubscriptionEnd] > GETDATE())) AND (S.[Id] <>
(SELECT MIN(S2.[Id])
FROM [dbo].[ClientSubscriptions] AS S2
WHERE ((S2.[ClientId] = C.[Id]) AND (S2.[IsDeleted] = 0)))))) > 0) THEN 1 ELSE 0 END) AS BIT) AS IsPayingCustomer, COALESCE
((SELECT MAX(MonthlyPrice) AS Expr1
FROM dbo.ClientSubscriptions AS S
WHERE (ClientId = C.Id) AND (IsDeleted = 0) AND (SubscriptionEnd IS NULL OR
SubscriptionEnd > GETDATE()) AND (MonthlyPrice > 0)), 0.00) AS ActiveSubscriptionMonthlyPrice, MAX(ClientStatus) AS Status, MAX(Phone1) AS Phone, MAX(Phone2) AS Phone2,
(SELECT Code
FROM dbo.DiscountCoupons AS DC
WHERE (Code =
(SELECT TOP (1) DiscountCouponCode
FROM dbo.ClientPayments AS CP
WHERE (ClientId = C.Id)
ORDER BY Id))) AS DiscountCouponCode,
(SELECT IssuedTo
FROM dbo.DiscountCoupons AS DC
WHERE (Code =
(SELECT TOP (1) DiscountCouponCode
FROM dbo.ClientPayments AS CP
WHERE (ClientId = C.Id)
ORDER BY Id))) AS DiscountCouponIssuedTo,
(SELECT ClientDiscount
FROM dbo.DiscountCoupons AS DC
WHERE (Code =
(SELECT TOP (1) DiscountCouponCode
FROM dbo.ClientPayments AS CP
WHERE (ClientId = C.Id)
ORDER BY Id))) AS DiscountCouponClientDiscount, COALESCE
((SELECT COUNT(Id) AS Expr1
FROM dbo.ClientFiles AS F
WHERE (ClientId = C.Id)), 0) AS TotalFilesCount, COALESCE
((SELECT SUM(FileSize) AS Expr1
FROM dbo.ClientFiles AS F
WHERE (ClientId = C.Id)), 0) / 1048576.0 AS TotalFilesSize, CAST(MAX(CASE WHEN C.CrmEnded = 1 THEN 1 ELSE 0 END) AS BIT) AS CrmEnded, MAX(CrmStatus) AS CrmStatus, MAX(CrmUnuseReason)
AS CrmUnuseReason,
(SELECT COUNT(1) AS Expr1
FROM dbo.Tipulog_Crm_Calls_new AS CC
WHERE (Cust_id = C.Id)) AS CrmCallCount
FROM dbo.Clients AS C
WHERE (IsDeleted = 0)
GROUP BY Id
I will add a second answer, which is the complete sql. This has of course not been tested as we have no access to your data, but I think you should be able to debug it yourself. There are many pointers in this code that should show you how to go.
The basic thing is to take out all of the correlated queries and put them as subqueries. The only reason to do this is all the Max/Min you use - I would look at those as if they are not necessary depending on your data then you should take them out and join to the tables directly. All the subqueries are left joins - again make them normal joins if you can depending on your data.
Also took out the outside group by Id, as 99% sure this is not necessary, as is the Top 100% bit.
SELECT BusinessTitle, ClientName, ClientType AS Type, CreatedWhen,
CASE WHEN C.[CreatedBy] IS NULL THEN 'Client' ELSE 'Admin' END) AS CreatedBy,
CAST(CASE WHEN C.IsDisabled = 1 THEN 1 ELSE 0 END AS BIT) AS IsDisabled,
ReferenceSource, OtherReferenceSource, Address,
ApplicationByName.FullName AS ClientAdmin,
ApplicationByName.Email AS Email,
Cities.Name AS City,
Patients.TotalPatientCount,
Patients.ActivePatientCount,
Patients.LastPatientAddition,
Treatments.TotalTreatmentCount,
Treatments.LastTreatmentAddition,
Therapists.TotalTherapistCount,
Therapists.ActiveTherapistCount,
Therapists.LastTherapistAddition,
Therapists.TherapistLastLoginDate
CAST(CASE WHEN Subscriptions.SubscriptionCount>0 then 1 else 0 end as BIT) as HasActiveSubscription,
Subscriptions.LastValidSubscriptionEnd
CAST(Subscriptions.IsPayingCustomer AS BIT) AS IsPayingCustomer,
COALESCE(ActiveSubscriptionMonthlyPrice,0) as ActiveSubscriptionMonthlyPrice
ClientStatus AS Status, Phone1 AS Phone, Phone2 AS Phone2,
ClientPayments.DiscountCouponCode,
DiscountCoupons.IssuedTo AS DiscountCouponIssuedTo,
DiscountCoupons.ClientDiscount AS DiscountCouponClientDiscount,
COALESCE(ClientFiles.TotalFilesCount,0) AS TotalFilesCount,
COALESCE(ClientFiles.TotalFilesSize,0) AS TotalFilesSize,
CAST((CASE WHEN C.CrmEnded = 1 THEN 1 ELSE 0 END) AS BIT) AS CrmEnded,
CrmStatus, CrmUnuseReason,
Crm_Calls.CrmCallCount
FROM dbo.Clients AS C
left join (
select A.UserName,
max(T.FirstName + ' ' + T.LastName) as FullName,
max(A.Email) as Email
from dbo.ApplicationUsers A
join dbo.Therapists T on T.ApplicationUserId=A.Id
group by A.Username
) ApplicationByName on ApplicationByName.UserName=C.ClientName
join dbo.Cities on Cities.ID=c.CityID
left join (
SELECT ClientId,
COUNT(*) AS TotalPatientCount,
sum(case when IsDeleted = 0 AND IsDisabled = 0 then 1 else 0 end) AS ActivePatientCount,
MAX(CreatedWhen) AS LastPatientAddition
FROM dbo.Patients
GROUP BY ClientId
) Patients on Patients.ClientId = C.Id
left join (
SELECT ClientId,
COUNT(*) AS TotalTreatmentCount,
MAX(CreatedWhen) AS LastTreatmentAddition
FROM dbo.Treatments
GROUP BY ClientId
) Treatments on Treatments.ClientID = C.Id
left join (
select T.ClientId,
count(distinct T.Id) as TotalTherapistCount,
sum(case when A.IsDeleted = 0 AND A.IsDisabled = 0 then 1 else 0 end) as ActiveTherapistCount,
max(A.CreatedWhen) as LastTherapistAddition,
max(A.LastLoginDate) as TherapistLastLoginDate
from Therapists T
left join dbo.ApplicationUsers A on A.Id=T.ApplicationUserId
group by T.ClientId
) Therapists on Therapists.ClientID = C.Id
left join (
SELECT S.ClientId,
count(*) as SubscriptionCount,
MAX(SubscriptionEnd) as LastValidSubscriptionEnd,
MAX(case when MinSub.Id!=S.ID then 1 else 0 end as IsPayingCustomer,
max(case when MonthlyPrice>0 then 0 end) as ActiveSubscriptionMonthlyPrice
FROM dbo.ClientSubscriptions S
join (
select ClientId, min(Id) as Id
from dbo.ClientSubscriptions
where IsDeleted=0
group by ClientId
) MinSub on MinSub.ClientId=ClientSubscriptions.ClientId
where IsDeleted=0 and (SubscriptionEnd is null or SubscriptionEnd>getdate())
group by ClientId
) Subscriptions on Subscriptions.ClientId=C.Id
left join (
select ClientId,
DiscountCouponCode,
row_number() over(partition by ClientId, order by Id) rn
from dbo.ClientPayments
) ClientPayments on ClientPayments.ClientId=C.ID and rn=1
left join dbo.DiscountCoupons on DiscountCoupons.Code=ClientPayments.DiscountCouponCode
left join (
select ClientId,
count(*) as TotalFilesCount,
sum(FileSize)/1048576.0 as TotalFilesSize
from dbo.ClientFiles
group by ClientId
) ClientFiles on ClientFiles.ClientId=Client.Id
left join (
SELECT Cust_id, COUNT(1) AS CrmCallCount
FROM dbo.Tipulog_Crm_Calls_new
group by Cust_id
) Crm_Calls on Crm_Calls.Cust_id=C.Id
WHERE C.IsDeleted = 0
This is a very partial answer, but you asked how to refer to a table once instead of multiple times in multiple subqueries.
This is an example of how you would replace all those subqueries to the Patients & Treatments tables, and also the cities table. You really need to learn about joins.
FROM dbo.Clients AS C
join dbo.Cities on Cities.ID=c.CityID
left join (
SELECT ClientId,
COUNT(*) AS TotalPatientCount,
sum(case when IsDeleted = 0 AND IsDisabled = 0 then 1 else 0 end) AS ActivePatientCount,
MAX(CreatedWhen) AS LastPatientAddition
FROM dbo.Patients
GROUP BY ClientId
) Patients on Patients.ClientId = C.Id
left join (
SELECT ClientId,
COUNT(*) AS TotalTreatmentCount,
MAX(CreatedWhen) AS LastTreatmentAddition
FROM dbo.Treatments
GROUP BY ClientId
) Treatments on Treatments.ClientID = C.Id
Then your column list replaces the subqueries to Patients and City like this:
Cities.Name AS City,
Patients.TotalPatientCount,
Patients.ActivePatientCount,
Patients.LastPatientAddition,
Treatments.TotalTreatmentCount,
Treatments.LastTreatmentAddition,
That should at least give you an idea.

Joining multiple tables results in duplicate rows

There are tow tables (Customer & Feedback) that have different information. The following query is almost correct, except that it results in duplicate rows. I only need unique rows as par customerId and NO for null value.
I tried the GROUP BY clause at the end but it gives error.
Select C.CustomerId,
C.FirstName,
C.LastName,
(SELECT CAST(CASE WHEN F.Id != null or F.Type = 'Query'
THEN 'YES' ELSE 'NO' END AS NVARCHAR(50))) as Query,
(SELECT CAST(CASE WHEN F.Id != null or F.Type = 'Feedback'
THEN 'YES' ELSE 'NO' END AS NVARCHAR(50))) as Feedback
FROM Customer C
LEFT JOIN Feedback F on F.CustomerId= C.CustomerId
Select * from Customer
Select * from Feedback
As Result I want to display only single row by customerId and to join the feedback table data like below...
You May Try either of the Below
SELECT
C.*,
Query = CASE WHEN PVT.Query IS NOT NULL THEN 'Yes' ELSE 'No' END,
Feedback = CASE WHEN PVT.Feedback IS NOT NULL THEN 'Yes' ELSE 'No' END
FROM Customer C
LEFT JOIN FeedBack
PIVOT
(
MAX(Id)
FOR
[Type] IN
(
[Query],[Feedback]
)
)Pvt
ON PVT.CustomerId = c.CustomerId
or Simply
SELECT
C.*,
Query = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='Query') THEN 'Yes' ELSE 'No' END,
Feedback = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='Feedback') THEN 'Yes' ELSE 'No' END
FROM Customer C
To Make it more Dynamic ou may Try this
DECLARE #SQL VARCHAR(MAX)
;WITH CTE
AS
(
SELECT
RN = ROW_NUMBER() OVER(PARTITION BY [Type] ORDER BY [Type]),
QRY = LTRIM(RTRIM([Type]))+' = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='''+LTRIM(RTRIM([Type]))+''') THEN ''Yes'' ELSE ''No'' END'
FROM FeedBack
)
SELECT
#SQL = 'SELECT
C.*'
+SUBSTRING(','+L.List,1,LEN(L.List)-1)
+' FROM Customer C'
FROM
(
SELECT
QRY + ', ' [text()]
FROM CTE
WHERE RN = 1
FOR XML PATH('')
)L(List)
EXEC(#SQL)
Please Refer this Sqlfiddle for detailed example
Select C.CustomerId,
C.FirstName,
C.LastName,
sum(case when F.Type = 'Query' then 1 else 0 end) > 0 as Query,
sum(case when F.Type = 'Feedback' then 1 else 0 end) > 0 as Feedback
FROM Customer C
LEFT JOIN Feedback F on F.CustomerId= C.CustomerId
GROUP BY C.CustomerId, C.FirstName, C.LastName
use case when
Select C.CustomerId,
C.FirstName,
C.LastName,
case when sum(case when F.Type = 'Query' then 1 else 0 end) > 0 then 'Yes' else 'NO' end as Query,
case when sum(case when F.Type = 'Feedback' then 1 else 0 end) > 0 then 'Yes' else 'NO' End as Feedback
FROM Customer C
LEFT JOIN Feedback F on F.CustomerId= C.CustomerId
GROUP BY C.CustomerId, C.FirstName, C.LastName
Try below query using subquery:
select *,case when query=1 then 'Yes' else 'No' end as query,
case when feedback=1 then 'Yes' else 'No' end as feedbackfrom
(select CustomerId, firstname,lastname,
sum(CASE WHEN Type = 'Query'
THEN 1 ELSE 0 END) as Query,
sum(CASE WHEN Type = 'Feedback'
THEN 1 ELSE 0 END) as Feedback from Customer C
LEFT JOIN Feedback F on F.CustomerId= C.CustomerId
group by CustomerId, firstname,lastname)a
Try this:
select c.CustomerId,
c.FirstName,
c.LastName,
case when q.CustomerId is null then 'NO' else 'YES' end Query,
case when f.CustomerId is null then 'NO' else 'YES' end Feedback,
from Customers c
left join (select customerId from Feedback where Type = 'Query' ) q on c.CustomerId = q.CustomerId
left join (select customerId from Feedback where Type = 'Feedback' ) f on c.CustomerId = q.CustomerId

SQL Where in for Many to Many Join Table

I have the following (moderately epic query) which I have been writing
Select *
from
(Select
Salutation,
FirstName, LastName, FullName,
PhotoUrl, CountryCode, Email, Birthday,
Gender, HomePhone, M.MemberId, IDType, JoinDate,
HomeLocation, HomeLocationId,
Region.Name as RegionName,
M.MembershipId,
coalesce(case
when Package.PackageIsReoccuring = 1 then 'Recurring'
when Package.PackageIsSession = 1 then 'Paid In Full'
when membership.TotalPrice = 0 then 'Free'
when Package.PackagePayInFull = 1 then 'Paid In Full'
end, 'N/A') as PackageTerm,
coalesce(PackageType.Name, 'N/A') as PackageType,
coalesce(membershipstate.name, 'N/A') as MembershipState,
MembershipStartDate =
case
when membership.StartDate IS NULL
then ''
else CONVERT(varchar(50),membership.StartDate)
end,
MembershipEndDate =
case
when membership.EndDate IS NULL
then ''
else CONVERT(varchar(50),membership.EndDate)
end,
Region.Id as RegionId
from
(select
AspNetUsers.Salutation,
AspNetUsers.FirstName, AspNetUsers.LastName,
CONCAT (AspNetUsers.FirstName, ' ', AspNetUsers.LastName) as FullName,
AspNetUsers.PhotoUrl, AspNetUsers.CountryCode, AspNetUsers.Email,
AspNetUsers.Birthday, AspNetUsers.Gender,
AspNetUsers.HomePhone as HomePhone,
Member.Id as MemberId, Member.IDType, Member.JoinDate,
HomeLocation.Name as HomeLocation,
HomeLocation.Id as HomeLocationId,
(case when (select top 1 id from membership where membership.memberid = Member.id and (membership.membershipstateid = 1 or membership.membershipstateid = 6)) IS NULL Then (select top 1 id from membership where membership.memberid = Member.id order by membership.enddate desc) ELSE (select top 1 id from membership where membership.memberid = Member.id and (membership.membershipstateid = 1 or membership.membershipstateid = 6)) END) as MembershipId
from
AspNetUsers
join
Member on AspNetUsers.id = Member.aspnetuserid
join
Location as HomeLocation on Member.HomeLocationId = HomeLocation.id) as M
left join
Membership on M.MembershipId = Membership.Id
left join
Package on Membership.packageid = Package.Id
left join
PackageType on Package.packagetypeid = PackageType.Id
left join
MembershipState on Membership.membershipstateid = MembershipState.Id
left join
Region on Membership.RegionId = Region.Id) as Result
order by
Result.LastName desc
I have a final join table which I want to use which is a many-to-many relationship on Region. Region has a Join Table (RegionLocations) which is a join between Region and Locations.
With my query below I would like to get all results where the HomeLocationId = 2 OR he has a LocationId (from RegionLocations) which also contains 2. The RegionId is a nullable value and isn't always populated.
How can I get this? Do I need to return values into a CSV? This final hurdle is a battle..
Thanks
You could extend this:
left join
Region on Membership.RegionId = Region.Id) as Result
to this:
left join
Region on Membership.RegionId = Region.Id
where M.HomeLocationId = 2
or Region.Id in (select RegionId from RegionLocation where LocationId = 2)
) as Result
Some other remarks about your query:
The fields MembershipStartDate and MembershipEndDate can be evaluated more concisely as:
COALESCE(CONVERT(varchar(50),membership.StartDate), '') as MembershipStartDate,
COALESCE(CONVERT(varchar(50),membership.EndDate), '') as MembershipEndDate,
The inner field MembershipId is defined with three sub-queries in a case when, which can be shortened to just one query. It uses in instead of an or condition, and puts it in the order by clause in a way that gets the priority right:
(select top 1 id
from membership
where membership.memberid = Member.id
order by case when membership.membershipstateid in (1,6) then 0 else 1 end,
membership.enddate desc
) as MembershipId
Finally, if you just have an outer query that performs a select * from (...) order by, then why not skip that outer query and perform that order by on the inner query direcly?

SQL join two simple query with count and groupby

hello i have 2 queries and i wanna join together but i don't know how...
SELECT *, count(*) as invii
FROM professionisti JOIN preventivi_invii ON
professionisti.email=preventivi_invii.email
GROUP BY professionisti.email
HAVING invii> 300
SELECT *, count(*) as acquisti
FROM professionisti JOIN contatti_acquistati ON
professionisti.email=contatti_acquistati.email
GROUP BY professionisti.email
HAVING acquisti> 5
the problem for me is multiple count and the group by with same column.
thank u
How about the below query. You would just change the WHERE clause to meet your needs.
SQL Fiddle Example:
SELECT * FROM
(
SELECT p.email,
CASE WHEN ISNULL(m1.invii) THEN 0 ELSE m1.invii END AS invii,
CASE WHEN ISNULL(m2.acquisti) THEN 0 ELSE m2.acquisti END AS acquisti
FROM professionisti p
LEFT JOIN
(
SELECT pp.email, COUNT(*) AS invii
FROM preventivi_invii pp
GROUP BY pp.email
) AS m1 ON p.email = m1.email
LEFT JOIN
(
SELECT c.email, COUNT(*) AS acquisti
FROM contatti_acquistati c
GROUP BY c.email
) AS m2 ON p.email = m2.email
) AS mm
WHERE mm.invii = 0
OR mm.acquisti = 0;
Or you could use:
SELECT * FROM
(
SELECT p.email,
(
SELECT
CASE WHEN ISNULL(COUNT(*)) THEN 0 ELSE COUNT(*) END
FROM preventivi_invii pp
WHERE pp.email = p.email
) AS invii,
(
SELECT
CASE WHEN ISNULL(COUNT(*)) THEN 0 ELSE COUNT(*) END
FROM contatti_acquistati c
WHERE c.email = p.email
) AS acquisti
FROM professionisti p
) AS mm
WHERE mm.invii = 0
OR mm.acquisti = 0

(ORDER BY CASE WHEN) ordering by subquery

I need to order my results by int column ascending, but I want to get only rows with numbers (0...10000) but default ordering gives me rows with null values for this column before numbers. I googled solution which set rows with null into the end of ordering (after all numbers) it looks like
SELECT ProductName
FROM Products
ORDER BY
CASE WHEN Position is null THEN 1 ELSE 0 END,
Position
So I my query looks like:
SELECT c.CompanyId, c.CompanyName, c.CompanyCategoryId, cc.CompanyCategoryName, c.HQCountryISO, c.CrunchBaseUrl,c.AngelListUrl,
(SELECT MAX(mf.NumLikes) FROM MeasurementFacebook mf
JOIN FacebookAccount f ON f.CompanyId = c.CompanyId
WHERE f.FacebookAccountId in (mf.FacebookAccountId)) as Likes,
(SELECT MAX(mt.NumFollowers) FROM MeasurementTwitter mt
JOIN TwitterAccount t ON t.CompanyId = c.CompanyId
WHERE t.TwitterAccountId in (mt.TwitterAccountId)) as Followers,
(SELECT MAX(ma.AlexaRanking) FROM MeasurementAlexa ma
JOIN Website w ON w.CompanyId = c.CompanyId
WHERE w.WebsiteId in (ma.WebsiteId)) as AlexaRank
FROM Company c
JOIN CompanyCategory cc ON c.CompanyCategoryId = cc.CompanyCategoryId
WHERE c.HQCountryISO = 'FRA'
ORDER BY CASE WHEN AlexaRank IS NULL THEN 1 ELSE 0 END, AlexaRank
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
As you can see, AlexaRank is the result of third subquery, and I want to order result by this column. But I have an error which says:
Msg 207, Level 16, State 1, Line 14
Invalid column name 'AlexaRank'.
What I'm doing wrong? Thanks
While you can use an alias in the ORDER BY clause, you can't use an alias in an expression, easiest solution is to plop it in a cte/subquery:
;WITH cte AS (SELECT c.CompanyId
, c.CompanyName
, c.CompanyCategoryId
, cc.CompanyCategoryName
, c.HQCountryISO
, c.CrunchBaseUrl
,c.AngelListUrl
,(SELECT MAX(mf.NumLikes)
FROM MeasurementFacebook mf
JOIN FacebookAccount f ON f.CompanyId = c.CompanyId
WHERE f.FacebookAccountId in (mf.FacebookAccountId)) as Likes
,(SELECT MAX(mt.NumFollowers)
FROM MeasurementTwitter mt
JOIN TwitterAccount t ON t.CompanyId = c.CompanyId
WHERE t.TwitterAccountId in (mt.TwitterAccountId)) as Followers
,(SELECT MAX(ma.AlexaRanking)
FROM MeasurementAlexa ma
JOIN Website w ON w.CompanyId = c.CompanyId
WHERE w.WebsiteId in (ma.WebsiteId)) as AlexaRank
FROM Company c
JOIN CompanyCategory cc ON c.CompanyCategoryId = cc.CompanyCategoryId
WHERE c.HQCountryISO = 'FRA')
SELECT *
FROM cte
ORDER BY CASE WHEN AlexaRank IS NULL THEN 1 ELSE 0 END, AlexaRank
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
Very inefficient code but you could do something like the following. Basically wrap your initial query in a common table expression so you don't need to rewrite your 3rd sub-select in your order by.
SELECT * FROM (
SELECT c.companyid,
c.companyname,
c.companycategoryid,
cc.companycategoryname,
c.hqcountryiso,
c.crunchbaseurl,
c.angellisturl,
(SELECT Max(mf.numlikes)
FROM measurementfacebook mf
JOIN facebookaccount f
ON f.companyid = c.companyid
WHERE f.facebookaccountid IN ( mf.facebookaccountid )) AS Likes,
(SELECT Max(mt.numfollowers)
FROM measurementtwitter mt
JOIN twitteraccount t
ON t.companyid = c.companyid
WHERE t.twitteraccountid IN ( mt.twitteraccountid )) AS Followers,
(SELECT Max(ma.alexaranking)
FROM measurementalexa ma
JOIN website w
ON w.companyid = c.companyid
WHERE w.websiteid IN ( ma.websiteid )) AS AlexaRank
FROM company c
JOIN companycategory cc
ON c.companycategoryid = cc.companycategoryid
WHERE c.hqcountryiso = 'FRA' ) Q
ORDER BY CASE
WHEN Q.AlexaRank IS NULL THEN 1
ELSE 0
END,
Q.AlexaRank