Select top 1 subquery with parameters (SQL) - sql-server

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?

Related

Count in CTE query with variables

I have a query and want to COUNT all the related ids from other table.
I am using CTE and I also assigning variables.
When I print I get all the ids but how can I COUNT the same ids? I mean if I have an id "254aswer" 3 times it should show 3
This is the query:
;WITH cte AS (
select q.fecha, '31' as cdocu, q.Cotizacion__c, cli.codcli,
q."name", q.RUC__c, c.Nombre_contacto__c as atte, a.Direcci_n__c,
q.Referencia__c, q.Requisicion__c, con.mone, q.T_Cambio__c, q.TotalPrice,
(q.TotalPrice*q.IGV__c)/100 as toti,(q.TotalPrice+
(q.TotalPrice*q.IGV__c)/100) as totn, '0' as flag, ven.codven, cd.codcdv,
'00' as codscc,q.fecha as fven ,q.Validez_por__c,'0' as selchk,'0' as
estado,q.Descripcion__c,'0' as word,'0' as frontera,'0' as
idalias,q.T_Cambio__c as tcme,'0'as idcliente,'0' as idcontacto,'0' as
persnt,'0'as flag_rp,'0' as origen,ti.IDdespacho,'0' as nrosal,'0' as
iddirfis,tr.codtra,q.fecha as fecreg,ROW_NUMBER() OVER(ORDER BY
q.Cotizacion__c) AS 'Row1', q.Id
from quote AS q
LEFT JOIN tbl01cor cor ON q.Cotizacion__c = cor.nroini
LEFT JOIN mst01cli cli ON q.RUC__c = cli.ruccli
LEFT JOIN Contact c ON q.RUC__c = c.RUC_contacto__c
LEFT JOIN Account a ON q.RUC__c = a.RUC__c
LEFT JOIN tbl01cdv cd ON q.Condicion__c = cd.nomcdv
LEFT JOIN tbl_tipo_despacho ti ON q.T_Entrega__c = ti.despacho
LEFT JOIN tbl01tra tr ON q.Transportista__c = tr.nomtra
LEFT JOIN consulta con ON q.CurrencyIsoCode = con.CurrencyIsoCode
LEFT JOIN tbl01ven ven ON q.Vendedor__c = ven.nomven
select #fecha = cte.fecha, #cdocu = cte.cdocu, #ndocu = cte.Cotizacion__c, #codcli = cte.codcli, #nomcli = cte."name", #ruccli = cte.RUC__c, #atte = cte.atte,
#dirent = cte.Direcci_n__c, #nrefe = cte.Referencia__c, #requ = cte.Requisicion__c, #mone = cte.mone, #tcam = cte.T_Cambio__c, #tota = cte.TotalPrice, #toti = cte.toti,
#totn = cte.totn, #flag = cte.flag, #codven = cte.codven, #codcdv = cte.codcdv,#codscc = cte.codscc,#fven = cte.fven, #dura =cte.Validez_por__c, #selchk = cte.selchk,
#estado = cte.estado, #obsere = cte.Descripcion__c, #word= cte.word, #frontera = cte.frontera,#idalias = cte.idalias,#tcme = cte.tcme, #idcliente = cte.idcliente,
#idcontacto = cte.idcontacto, #persnt = cte.persnt, #flag_rp= cte.flag_rp, #origen = cte.origen,#tipent = cte.IDdespacho, #nrosal = cte.nrosal,
#iddirfis = cte.iddirfis, #CodTra = cte.codtra, #fecreg = cte.fecreg, #ID = cte.Id
FROM cte
--WHERE cte.fecha >= dateadd(day,datediff(day,0,GETDATE()),0)
WHERE Row1 = #COUNTER +1
SET #ITEM = (Select COUNT(*) from QuoteLineItem where Id = #ID)
PRINT #ITEM
I tried to create a new select like this:
SET #ITEM = (Select COUNT(*) from QuoteLineItem where Id = #ID)
But it only count all the items and I need to show the count for each of the ids. How can I get that?
I fixed it with this:
select count(QuoteId) from QuoteLineItem Where QuoteId = q.Id Group by QuoteId

Getting TFS work items on SSMS

I need some help mimicking a TFS query.
I have tried writing the following SQL query to do so but I am not able to get a matching population:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF OBJECT_ID('tempdb.dbo.#LastRecord') IS NOT NULL DROP TABLE #LastRecord
SELECT System_Id
, LastUpdatedDateTime = MAX(LastUpdatedDateTime)
INTO #LastRecord
FROM [dimWorkItem]
GROUP BY System_Id
SELECT distinct ID = w.System_Id
--Cannot find Department
, Department = '?'
, w.TeamProjectSK
, RequestedByUser = w.Custom_RequestedBy
, Title = w.System_Title
, [Priority] = w.Microsoft_VSTS_Common_Priority
, Activity = w.Microsoft_VSTS_Common_Activity
, da.AreaPath
, [State] = w.System_State
, Reason = w.System_Reason
, ClosedDate = w.Microsoft_VSTS_Common_ClosedDate
, ActivatedDate = Microsoft_VSTS_Common_ActivatedDate
, DevHours = Custom_DevHours
, CreatedDate = w.System_CreatedDate
, AssignedTo = dp.Name
, [Week] = CASE WHEN (w.System_State = 'Active' OR Microsoft_VSTS_Common_ClosedDate >= dateadd(d,-7,CONVERT(Date,getdate(),1))) THEN 'Current'
WHEN (w.System_State = 'Active' OR Microsoft_VSTS_Common_ClosedDate >= dateadd(d,-14,CONVERT(Date,getdate(),1)) AND Microsoft_VSTS_Common_ClosedDate < dateadd(d,-7,CONVERT(Date,getdate(),1))) THEN 'Last'
ELSE 'Previous' END
, TSRNumber = Custom_TSRNumber
FROM
(Select * from (select *, rn = row_number() over(partition by w1.System_Id, w1.TeamProjectSK, w1.System_State order by w1.System_Rev desc)
from dbo.DimWorkItem w1) d where rn = 1) w
JOIN #LastRecord l ON w.System_Id = l.System_Id AND w.LastUpdatedDateTime = l.LastUpdatedDateTime
LEFT OUTER JOIN dbo.DimArea da ON w.AreaSK = da.AreaSK
LEFT OUTER JOIN DimPerson dp ON w.System_AssignedTo__PersonSK = dp.PersonSK
WHERE System_WorkItemType = 'Task'
AND da.AreaPath like '\LOS\Reporting%'
AND w.Microsoft_VSTS_Common_Priority < 4
Also if anyone knows where I could find the department field as I am not sure whether it is a custom field or not.
SQL Server 2014: 12.0
TFS: 12.0
Visual studio professional 2015: 14.0
Thank you in advance for your suggestions!
I found a solution although still not able to find the the Department field :
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF OBJECT_ID('tempdb.dbo.#LastRecord') IS NOT NULL DROP TABLE #LastRecord
SELECT System_Id, LastChangedDate = MAX(System_ChangedDate)
INTO #LastRecord
FROM [dimWorkItem]
GROUP BY System_Id
DECLARE #FromDateWeek DATE
DECLARE #FromDateTwoWeek DATE
SET #FromDateWeek = dateadd(d,-7,CONVERT(Date,getdate(),1))
SET #FromDateTwoWeek = dateadd(d,-14,CONVERT(Date,getdate(),1))
--SELECT #FromDate
SELECT ID = w.System_Id
--Cannot find Department
, Department = '?'
, w.TeamProjectSK
, RequestedByUser = w.Custom_RequestedBy
, Title = w.System_Title
, [Priority] = w.Microsoft_VSTS_Common_Priority
, Activity = w.Microsoft_VSTS_Common_Activity
, da.AreaPath
, [State] = w.System_State
, Reason = w.System_Reason
, ClosedDate = w.Microsoft_VSTS_Common_ClosedDate
, ActivatedDate = Microsoft_VSTS_Common_ActivatedDate
, DevHours = Custom_DevHours
, CreatedDate = w.System_CreatedDate
, AssignedTo = dp.Name
, [Week] = CASE WHEN w.Microsoft_VSTS_Common_ClosedDate >= #FromDateWeek OR w.System_State = 'Active' THEN 'Current'
WHEN (w.Microsoft_VSTS_Common_ClosedDate >= #FromDateTwoWeek AND w.Microsoft_VSTS_Common_ClosedDate < #FromDateWeek)
OR w.Microsoft_VSTS_Common_ClosedDate < #FromDateWeek THEN 'Last'
ELSE 'Previous' END
FROM [dimWorkItem] w
JOIN #LastRecord l ON w.System_Id = l.System_Id AND w.System_ChangedDate = l.LastChangedDate
LEFT OUTER JOIN DimPerson dp ON w.System_AssignedTo__PersonSK = dp.PersonSK
LEFT OUTER JOIN dbo.DimArea da ON w.AreaSK = da.AreaSK
WHERE
da.AreaPath LIKE '\LOS\Reporting%'
AND System_WorkItemType = 'Task'
AND (Microsoft_VSTS_Common_ClosedDate >= #FromDateTwoWeek
OR w.System_State = 'Active')
AND ISNULL(Microsoft_VSTS_Common_Priority,0) < 4
AND w.System_Reason <> 'Obsolete'

Convert an UPDATE statement to a SELECT statement

Sample code:
UPDATE
TEMP_TABLE_NTI_D_test1 TEMP_NTID
SET
TEMP_NTID.WEEKLY_FLAG='Y',
TEMP_NTID.PROGRAM_COUNT=0,
FROM
(
SELECT
*
FROM
(
SELECT
st_date,
NET_CODE,
PR_CODE,
ST_HR,
ST_MIN,
sId,
DURATION,
REC_FLAG,
ROW_NUMBER() OVER(PARTITION BY NET_CODE,PR_CODE,
REC_FLAG,st_date,sId
ORDER BY ST_HR,ST_MIN) ROW_NUM
FROM
TEMP_TABLE_NTI_D_test1
WHERE
BRK_IND = 0
AND GAP_IND = 'Y'
AND COM_IND != 'Y' ) AB
WHERE
ROW_NUM > 1) TEMP_TABLE_GAPPED_ZEROES
WHERE
TEMP_NTID.NET_CODE = TEMP_TABLE_GAPPED_ZEROES.NET_CODE
AND TEMP_NTID.PR_CODE = TEMP_TABLE_GAPPED_ZEROES.PR_CODE
AND TEMP_NTID.ST_HR = TEMP_TABLE_GAPPED_ZEROES.ST_HR
AND TEMP_NTID.ST_MIN = TEMP_TABLE_GAPPED_ZEROES.ST_MIN
AND TEMP_NTID.DURATION = TEMP_TABLE_GAPPED_ZEROES.DURATION
AND TEMP_NTID.REC_FLAG = TEMP_TABLE_GAPPED_ZEROES.REC_FLAG
AND TEMP_NTID.st_date = TEMP_TABLE_GAPPED_ZEROES.st_date
;
Instead of updating the column I would like to receive a SELECT statement that gives a readout of each row (that would be updated if it was an UPDATE statement).
This is the most straightforward translation from the update.
select
TEMP_NTID.* --Select the table's records instead of update.
FROM
(
SELECT
*
FROM
(
SELECT
st_date,
NET_CODE,
PR_CODE,
ST_HR,
ST_MIN,
sId,
DURATION,
REC_FLAG,
ROW_NUMBER() OVER(PARTITION BY NET_CODE,PR_CODE,
REC_FLAG,st_date,sId
ORDER BY ST_HR,ST_MIN) ROW_NUM
FROM
TEMP_TABLE_NTI_D_test1
WHERE
BRK_IND = 0
AND GAP_IND = 'Y'
AND COM_IND != 'Y' ) AB
WHERE
ROW_NUM > 1) TEMP_TABLE_GAPPED_ZEROES
,TEMP_TABLE_NTI_D_test1 TEMP_NTID --Move the updated table here.
WHERE
TEMP_NTID.NET_CODE = TEMP_TABLE_GAPPED_ZEROES.NET_CODE
AND TEMP_NTID.PR_CODE = TEMP_TABLE_GAPPED_ZEROES.PR_CODE
AND TEMP_NTID.ST_HR = TEMP_TABLE_GAPPED_ZEROES.ST_HR
AND TEMP_NTID.ST_MIN = TEMP_TABLE_GAPPED_ZEROES.ST_MIN
AND TEMP_NTID.DURATION = TEMP_TABLE_GAPPED_ZEROES.DURATION
AND TEMP_NTID.REC_FLAG = TEMP_TABLE_GAPPED_ZEROES.REC_FLAG
AND TEMP_NTID.st_date = TEMP_TABLE_GAPPED_ZEROES.st_date
;

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

Two sorted subqueries into one result

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.

Resources