Two sorted subqueries into one result - sql-server

So I have two subqueries that return the same columns from the same table
Query #1:
SELECT E.Id,E.Title,E.LocationId,P.LocationId,E.DepartmentId,P.DepartmentId,E.DateCreated,E.IsActive,E.IsHotJob,E.RequisitionId,E.RequisitionIdString,E.RewardSettingId,E.EmploymentOpportunityStatusId
FROM EmploymentOpportunities E, Profiles P
WHERE E.EmploymentOpportunityStatusId = 9 AND E.IsActive = 1 AND E.IsHotjob = 1
AND P.Id = 'C5F07EBB-CE81-4133-A462-241A5F84D418' AND (P.DepartmentId != E.DepartmentId AND P.LocationId != E.LocationId)
ORDER BY E.DateCreated DESC
Query #2:
SELECT E.Id,E.Title,E.LocationId,P.LocationId,E.DepartmentId,P.DepartmentId,E.DateCreated,E.IsActive,E.IsHotJob,E.RequisitionId,E.RequisitionIdString,E.RewardSettingId,E.EmploymentOpportunityStatusId
FROM EmploymentOpportunities E, Profiles P
WHERE E.EmploymentOpportunityStatusId = 9 AND E.IsActive = 1 AND E.IsHotjob = 0 AND
P.Id = 'C5F07EBB-CE81-4133-A462-241A5F84D418' AND (P.DepartmentId = E.DepartmentId OR P.LocationId = E.LocationId)
ORDER BY E.DateCreated DESC
I want this two queries combines into one but preserve the order they have, so somehow stack Query #1 onto Query #2.
Is this possible?

SELECT 1 SetNumber, E.Id,E.Title,E.LocationId,P.LocationId,E.DepartmentId,
P.DepartmentId,E.DateCreated,E.IsActive,E.IsHotJob,E.RequisitionId,
E.RequisitionIdString,E.RewardSettingId,E.EmploymentOpportunityStatusId
FROM EmploymentOpportunities E, Profiles P
WHERE E.EmploymentOpportunityStatusId = 9 AND E.IsActive = 1
AND E.IsHotjob = 1 P.Id = 'C5F07EBB-CE81-4133-A462-241A5F84D418'
AND (P.DepartmentId != E.DepartmentId AND P.LocationId != E.LocationId)
union all
SELECT 2, E.Id,E.Title,E.LocationId,P.LocationId,E.DepartmentId,P.DepartmentId,
E.DateCreated,E.IsActive,E.IsHotJob,E.RequisitionId,E.RequisitionIdString,
E.RewardSettingId,E.EmploymentOpportunityStatusId
FROM EmploymentOpportunities E, Profiles P
WHERE E.EmploymentOpportunityStatusId = 9 AND E.IsActive = 1
AND E.IsHotjob = 0 AND P.Id = 'C5F07EBB-CE81-4133-A462-241A5F84D418'
AND (P.DepartmentId = E.DepartmentId OR P.LocationId = E.LocationId)
ORDER BY SetNumber, DateCreated desc

Just use UNION ALL
SELECT * FROM
(
Your Query1
UNION ALL // do not use order by here
Your Query2
) AS someName
ORDER BY yourColumn DESC
You can also use UNION - but it will filter out duplicates if any.

Related

EF LINQ Count by Grouped field

I have the following data schema:
With the following LINQ query:
var profiles = (
from p in context.BusinessProfiles
join u in context.Users on p.UserId equals u.Id
join addr in context.BusinessAddress on p.ProfileId equals addr.ProfileId into addrj
from addr in addrj.DefaultIfEmpty()
join pa in context.BusinessProfileActivities on p.ProfileId equals pa.ProfileId into paj
from paIfNull in paj.DefaultIfEmpty()
where p.ProfileId >= 137 && p.ProfileId <= 139
group new { p, u, addr, paIfNull }
by new {
p.ProfileId,
p.CompanyName,
p.Email,
UserEmail = u.Email,
addr.City, addr.Region,
addr.Country,
ActivityProfileId = paIfNull.ProfileId }
into pg
select new {
pg.Key.ProfileId,
pg.Key.CompanyName,
Email = pg.Key.Email ?? pg.Key.UserEmail,
pg.Key.City,
pg.Key.Region,
pg.Key.Country,
MatchingActivities = pg.Key.ActivityProfileId > 0 ? pg.Count() : 0
} into result
orderby result.MatchingActivities descending
select result
);
Which results with:
This result is corrent (ProfileId 137 has 0 activities, 138 has 1 and 139 has 2), but it produces the following SQL:
SELECT [b].[ProfileId], [b].[CompanyName], COALESCE([b].[Email], [a].[Email]) AS [Email], [b0].[City], [b0].[Region], [b0].[Country],
CASE WHEN [b1].[ProfileId] > CAST(0 AS bigint) THEN COUNT(*)
ELSE 0
END AS [MatchingActivities]
FROM [BusinessProfiles] AS [b]
INNER JOIN [AspNetUsers] AS [a] ON [b].[UserId] = [a].[Id]
LEFT JOIN [BusinessAddress] AS [b0] ON [b].[ProfileId] = [b0].[ProfileId]
LEFT JOIN [BusinessProfileActivities] AS [b1] ON [b].[ProfileId] = [b1].[ProfileId]
WHERE ([b].[ProfileId] >= CAST(137 AS bigint)) AND ([b].[ProfileId] <= CAST(139 AS bigint))
GROUP BY [b].[ProfileId], [b].[CompanyName], [b].[Email], [a].[Email], [b0].[City], [b0].[Region], [b0].[Country], [b1].[ProfileId]
ORDER BY CASE
WHEN [b1].[ProfileId] > CAST(0 AS bigint) THEN COUNT(*)
ELSE 0
END DESC
In SQL, I can avoid both CASE WHEN if I use COUNT([b1].[ProfileId]) like this:
SELECT [b].[ProfileId], [b].[CompanyName], COALESCE([b].[Email], [a].[Email]) AS [Email], [b0].[City], [b0].[Region], [b0].[Country],
COUNT([b1].[ProfileId]) AS [MatchingActivities]
FROM [BusinessProfiles] AS [b]
INNER JOIN [AspNetUsers] AS [a] ON [b].[UserId] = [a].[Id]
LEFT JOIN [BusinessAddress] AS [b0] ON [b].[ProfileId] = [b0].[ProfileId]
LEFT JOIN [BusinessProfileActivities] AS [b1] ON [b].[ProfileId] = [b1].[ProfileId]
WHERE ([b].[ProfileId] >= CAST(137 AS bigint)) AND ([b].[ProfileId] <= CAST(139 AS bigint))
GROUP BY [b].[ProfileId], [b].[CompanyName], [b].[Email], [a].[Email], [b0].[City], [b0].[Region], [b0].[Country], [b1].[ProfileId]
ORDER BY [MatchingActivities] DESC
My question is, how can I count by grouped ActivityProfileId = paIfNull.ProfileId using LINQ and get EF to generate the above SQL?
I have tried so many variations resulting mostly in EF to SQL errors.
MatchingActivities = pg.Count(t => t.ActivityProfileId!= 0)
MatchingActivities = pg.Select(t => t.paIfNull.ProfileId).Distinct().Count(),
MatchingActivities = pg.Count(t => t.paIfNull != null),
All result in errors like System.InvalidOperationException: The LINQ expression ... could not be translated. or getting MatchingActivities as 1 instead of 0.
Related Q/A:
LINQ Count returning 1 instead of zero for an empty group
Group by in LINQ
How to write left join, group by and average in c# entity framework Linq
In short you can't! EF Core still doesn't support that.
See this:
https://github.com/dotnet/efcore/issues/17376
And also See:
https://stackoverflow.com/a/61878332/9212040

Select top 1 subquery with parameters (SQL)

I am removing a user function which finds shows item prices based on configurations but the function is too slow.
Therefore I'm trying to write a query to do the same. This query finds the latest price that matches the required criteria
This is kind of what I'm going for but I cannot figure out how to handle this requirement correctly:
(Intellisesnse says s.inventdimid does not exist in the h subquery)
SELECT s.salesid
,s.itemid
,h.price
FROM salesline s
LEFT OUTER JOIN (
SELECT TOP 1 p.price
,p.itemid
,p.dataareaid
,l.inventdimid
FROM inventitemprice p
JOIN inventdim d ON d.dataareaid = p.dataareaid
AND d.inventdimid = p.inventdimid
JOIN inventdim l ON l.dataareaid = p.dataareaid
AND (
l.configid = d.configid
OR d.configid = ''
)
AND (
l.inventcolorid = d.inventcolorid
OR d.inventcolorid = ''
)
AND (
l.inventsizeid = d.inventsizeid
OR d.inventsizeid = ''
)
AND (
l.inventstyleid = d.inventstyleid
OR d.inventstyleid = ''
)
AND (p.ACTIVATIONDATE < getdate())
AND l.inventsiteid = d.inventsiteid
WHERE pricetype = 0
AND l.inventdimid = s.inventdimid /* <========= */
AND p.dataareaid = 'lkc'
ORDER BY activationdate DESC
,d.configid DESC
,d.inventcolorid DESC
,d.INVENTSIZEID DESC
,d.inventstyleid DESC
) AS h ON h.itemid = s.itemid
AND h.DATAAREAID = s.DATAAREAID
AND h.INVENTDIMID = s.inventdimid
WHERE s.dataareaid = 'lkc'
AND s.SALESSTATUS = 1
What would be the appropriate method for querying this?

Data from same table with different where clauses into same view

I'm trying to get two kinds of data from same table into a view. I tried adding a join to same table with a different alias but it caused some null values.
I want the datatable as a single row , if possible. I know this can be done with union operator too but it causes multiple rows.
Here is my select
SELECT
COUNT(PO.OrderID) AS MerkezOnaySiparisAdet, SUM(PO.TotalPromotionPrice) AS MerkezOnayToplamSatis,
COUNT(PO2.OrderID) AS DepoOnaySiparişAdet, SUM(PO2.TotalPromotionPrice) AS DepoOnayToplamSatis
FROM PrmOrder PO
LEFT JOIN PrmOrder PO2 ON PO.OrderID = PO2.OrderId AND (PO2.OrderStatusID != 1 AND PO2.IsOrderApproved = 1 AND PO2.IsInventoryApproved = 0 AND (PO2.OrderStatusID = 2 OR PO2.OrderStatusID = 3))
WHERE 1=1
AND PO.OrderStatusID != 1
AND PO.IsOrderApproved = 0
AND (PO.OrderStatusID = 2 OR PO.OrderStatusID = 3)
What is the correct way of doing this?
Maybe, this isn't the best way, but you can use subquery. For example
SELECT
A1.Sum1,
A2.Sum2 FROM
(
SELECT
SUM(sod.OrderQty) sum1,
1 joinnumber
FROM
Sales.SalesOrderDetail sod
WHERE
sod.ProductID = 772
) AS A1
JOIN (
SELECT
SUM(sod.OrderQty) sum2,
1 joinnumber
FROM
Sales.SalesOrderDetail sod
WHERE
sod.ProductID = 773
) AS A2
ON A1.joinnumber = A2.joinnumber

How to update a table with a recursive CTE?

I hope you can help me
I have a problem over here, been trying to solve this but cannot figure out how. I have a simple table which represents reps and their leaders over cycles (time measures) like this:
RepID|LeaderID|CycleID
I need to calculate for each leader the whole tree below them only with certain status twice, because the formula is:
(All reps below the leader with status 1 or 2) - (All reps below the leader on the previous cycle with status 7)
My code is as follows:
update ccp
set ccp.Total_reps =
(
select isnull(COUNT(*),0)
from dbo.MCP_Reps_by_cycle ccp_total_reps
join dbo.MCP_Compensation_Plan cp_total_reps on cp_total_reps.ID_Compensation_Plan = ccp_total_reps.ID_Compensation_Plan and cp_total_reps.CycleID = #previous_cycle and cp_total_reps.Definitive = 1 and cp_total_reps.Active = 1
join dbo.F_Get_reps(ccp.RepID, #previous_cycle) r on r.RepID = ccp_total_reps.RepID
where ccp_total_reps.StatusDetailID in(1,2) and ccp_total_reps.Active = 1
)
-
(
select isnull(COUNT(*),0)
from dbo.MCP_Reps_by_cycle ccp_total_reps
join dbo.MCP_Compensation_Plan cp_total_reps on cp_total_reps.ID_Compensation_Plan = ccp_total_reps.ID_Compensation_Plan and cp_total_reps.CycleID = #previous_cycle_two and cp_total_reps.Definitive = 1 and cp_total_reps.Active = 1
join dbo.F_Get_reps(ccp.RepID, #previous_cycle_two) r on r.RepID = ccp_total_reps.RepID
where ccp_total_reps.StatusDetailID = 7 and ccp_total_reps.Active = 1
)
from dbo.MCP_Reps_by_cycle ccp
join dbo.MCP_Compensation_Plan cp on cp.ID_Compensation_Plan = ccp.ID_Compensation_Plan and cp.ID_Compensation_Plan = #ID_Compensation_Plan and cp.Active = 1
where ccp.Active = 1
What the F_Get_reps function does, is a simple recursive CTE:
RETURNS #MIT table (RepID int)
as
begin
with rep_network as (
select ccp.RepID
from dbo.MCP_Reps_by_cycle ccp
join dbo.MCP_Compensation_Plan cp on cp.ID_Compensation_Plan = ccp.ID_Compensation_Plan and cp.CycleID = #cycleid and cp.Definitive = 1 and cp.Active = 1
where ccp.Active = 1 and ccp.LeaderID = #repid
union all
select ccp_2.RepID
from dbo.MCP_Reps_by_cycle ccp_2
join dbo.MCP_Compensation_Plan cp_2 on cp_2.ID_Compensation_Plan = ccp_2.ID_Compensation_Plan and cp_2.CycleID = #cycleid and cp_2.Definitive = 1 and cp_2.Active = 1
join rep_network r on r.RepID = ccp_2.LeaderID
where ccp_2.Active = 1
)
insert into #MIT
select RepID
from rep_network
return
end
I know the call to the function is the problem, but I cannot figure out how to remove it.
Please help me
Thanks in advance

SQL Server query using Union - any good alternate possible?

I have a SQL Server query as:
SELECT top 1 vConsentInfo FROM
(
SELECT cons.vConsentInfo,cons.dTimeStamp ,logs.iPartnerProfileID
FROM H_OutMessageLog logs INNER JOIN H_OutMessageConsent cons on cons.iOutMessageQID = logs.iOutQueueID
WHERE logs.iPatID = 65686 and logs.iPracID = 4
UNION
SELECT cons.vConsentInfo,cons.dTimeStamp,Q.iPartnerProfileID
FROM H_OutMessageQueue Q INNER JOIN H_OutMessageConsent cons on cons.iOutMessageQID = Q.iOutQueueID
WHERE Q.iPatID = 65686 and Q.iPracID = 4
) A
WHERE A.iPartnerProfileID = Prof.IPartnerProfileID
Order BY dTimeStamp DESC
The table works as : a record get inserted into H_OutMessageQueue at the begining; then its inserted into H_OutMessageConsent...
Now there is a seperate worker process that processes records from H_OutMessageQueue and log them into H_OutMessageLog....
Can I get rid of this UNION thing ? Please note that this is a sub Query of a larger CTE query.
Yes, but it may not be better. You'll have to work this into your bigger query
SELECT TOP 1
cons.vConsentInfo,
ISNULL(logs.iPartnerProfileID , Q.iPartnerProfileID) AS iPartnerProfileID
FROM
H_OutMessageConsent cons
LEFT JOIN
H_OutMessageLog logs ON cons.iOutMessageQID = logs.iOutQueueID AND
logs.iPatID = 65686 and logs.iPracID = 4
LEFT JOIN
H_OutMessageQueue Q ON cons.iOutMessageQID = Q.iOutQueueID AND
Q.iPatID = 65686 and Q.iPracID = 4
WHERE
ISNULL(logs.iPartnerProfileID , Q.iPartnerProfileID) IS NOT NULL
ORDER BY
cons.dTimeStamp DESC
In addition to gbn reply. This will remove the extra burden from your query:).
SELECT top 1 vConsentInfo FROM
(
SELECT cons.vConsentInfo,cons.dTimeStamp ,logs.iPartnerProfileID
From
(
Select iPartnerProfileID FROM H_OutMessageLog logs
WHERE logs.iPatID = 65686 and logs.iPracID = 4
)logs
Left JOIN H_OutMessageConsent cons on cons.iOutMessageQID = logs.iOutQueueID
UNION
SELECT cons.vConsentInfo,cons.dTimeStamp,Q.iPartnerProfileID
From
(
Select iPartnerProfileID FROM H_OutMessageQueue Q
WHERE Q.iPatID = 65686 and Q.iPracID = 4
)Q
Left JOIN H_OutMessageConsent cons on cons.iOutMessageQID = Q.iOutQueueID
) A
WHERE A.iPartnerProfileID = Prof.IPartnerProfileID
Order BY dTimeStamp DESC

Resources