SQL Server Where clause with or statement - tsql

I have the following SQL stored procedure.
DECLARE #DepotID INT = 0
DECLARE #UserID INT = 72
SELECT EM.EmployeeSurname + ', ' + EM.EmployeeForename + ' ' + UPPER(LEFT(EM.EmployeeForename2,1)) EmployeeName
, EM.EmployeeMasterPayrollNumber
, PF.FrequencyDesc
, EM.EmpCode
, DPT.DepartmentName
, D.DepotDepotDescription
, CAST(EHE.EmployeeHolidayEntitlementRemainingEntitlementDays AS INT) EmployeeHolidayEntitlementRemainingEntitlementDays
, CAST(EHE.EmployeeHolidayEntitlementDaysAdjustment AS INT) EmployeeHolidayEntitlementDaysAdjustment
, CAST(EHE.EmployeeHolidayEntitlementHolidayTakenDays AS INT) EmployeeHolidayEntitlementHolidayTakenDays
, CAST(EHE.EmployeeHolidayEntitlementHolidayBuyBack AS INT) EmployeeHolidayEntitlementHolidayBuyBack
, EHE.EmployeeHolidayEntitlementComments
, CAST(EHE.EmployeeHolidayEntitlementCarriedForwardHolidayDays AS INT) EmployeeHolidayEntitlementCarriedForwardHolidayDays
, CAST(EHE.EmployeeHolidayEntitlementBankHoliday AS INT) EmployeeHolidayEntitlementBankHoliday
, CAST(EHE.EmployeeHolidayEntitlementBaseEntitlementDays AS INT) EmployeeHolidayEntitlementBaseEntitlementDays
FROM (((ttimport.EmployeeMaster EM
LEFT OUTER JOIN ttimport.PayrollFrequency PF ON EM.FrequencyDesc = PF.DescCode)
LEFT OUTER JOIN ttimport.Departments DPT ON EM.DepartmentName = DPT.DescCode)
LEFT OUTER JOIN ttimport.EmployeeHolidayEntitlement EHE ON EM.EmpCode = EHE.EmpCode)
LEFT OUTER JOIN ttimport.Depot D ON EM.DepotDepotDescription = D.DescCode
WHERE D.DescCode IN (SELECT DepotID FROM maintenance.UserDepot WHERE UserID = #UserID)
OR (D.DescCode = #DepotID)
AND EM.EmployeeMasterLeavingDate IS NULL
When it is first called the #DepotID is set to 0. But it can be called again where the #DepotID can be set to an Int value.
When the procedure is run with #DepotID set to 0 and a value in #UserID it works fine, but when I add a value to the #DepotID it produces a lot more records than it should.
I know there is an issue with the WHERE clause, but I cannot seem to get it to work correctly no matter what I try.
I have also tried the following in the WHERE clause:
WHERE D.DescCode = #DepotID
OR D.DescCode IN (SELECT DepotID FROM maintenance.UserDepot WHERE UserID = #UserID)

Related

T_SQL The multi part identifier could not be bound error

I have a query which works fine, but I am trying to create a dynamic pivot out of it to get a better end result table.
I found this on SO but I cant relate it to my issue.
The multi-part identifier could not be bound
My working code is this:
DECLARE #RangeDate as date
set #RangeDate = (select distinct cd.weDate from CM_DATA cd where cd.year = 2015 and cd.week = 45)
set #RangeDate = DATEADD(WW, -7, #RangeDate)
DECLARE #SQL as VARCHAR(MAX)
DECLARE #Columns AS VARCHAR(MAX)
SELECT #Columns =
COALESCE(#Columns + ', ','') + QUOTENAME(YearWeek)
FROM
(
SELECT DISTINCT YearWeek
FROM CM_DATA
where weDate >= #RangeDate
) AS B
SET #SQL = '
WITH PivotData AS
(
select cd.Country
, cd.Chain
, cd.YearWeek
, left(sm.Planogram, 2) as planogram
, cd.StoreNo
, cd.UID
, cd.ShortCode
, lp.Family
, lp.ColourShort
, pr.type
, cd.Volume
, ul.WOSOR
from vw_V2_UsrVarLst ul
left join CM_DATA cd on cd.Country = ul.CountryCode and cd.Chain = ul.Chain
left join V2_StoreMaster sm on sm.CountryCode = ul.CountryCode and sm.Chain = ul.Chain and sm.StoreNo = cd.StoreNo and sm.StoreNm = cd.StoreNm and cd.YearWeek between sm.YYYYWW and sm.YYYYWWEND
left join tblProducts pr ON pr.[COUNTRY CODE] = ul.CountryCode and pr.SKU = cd.UID
left join V2_LanguagePack LP ON LP.ShortCode = cd.ShortCode AND lp.Lang = ul.UsrLang
where cd.Country = ul.CountryCode and cd.Chain = ul.Chain and planogram is not null and left(cd.UID, 10) in (select lv.UID from V2_live lv where lv.CountryCode = ul.CountryCode and lv.Chain = ul.Chain and cd.YearWeek between lv.YYYYWW and lv.YYYYWWEND) and cd.weDate >= ' + #RangeDate + ' and sm.Planogram != ''Z''
)
select cd.Country
, cd.Chain
, left(sm.Planogram, 2) as planogram
, cd.StoreNo
, cd.UID
, cd.ShortCode
, lp.Family
, lp.ColourShort
, pr.type
, cd.Volume
, ' + #Columns + '
, ul.WOSOR
FROM PivotData
PIVOT
(
SUM(Volume)
FOR YearWeek
IN(' + #Columns + ')
) AS PivotResult'
EXEC (#SQL)
Can anyone spot what up here
KR
Martin
Try SELECT #SQL instead of your EXEC.
You probably must set the output to Text and use the query options (right click into the query window) to set the max length of text output to a higher value (maximum is 8192).
Than you can paste the result of your dynamic SQL into a new query window and execute this there. You should get a speaking error message and you should even jump to the right place with a double click...
Good luck!

How to get the rows position numbers of a table result

This is my code
Select #pos = Pos, #ptsReputacion = isnull(AA.PtsReputacion,0)
From
(Select
ROW_NUMBER() OVER (ORDER BY #ptsReputacion DESC) AS Pos
, USUARIO.CodUsuario
, PtsReputacion = (Select isnull(sum(Puntos),0) as Puntos
From USUARIO_RANKING_INTERES
Where USUARIO_RANKING_INTERES.CodUsuario = #codUsuario)
, USUARIO.CantIntentos as Intentos
, USUARIO.CantAciertos as Aciertos
, USUARIO.CantFallos as Fallos
, isnull(USUARIO.PG,0) as PG
, isnull(USUARIO.PE,0) as PE
, isnull(USUARIO.PP,0) as PP
, isnull(USUARIO.TiempoTotal,0) as TiempoTotal
From USUARIO) AA
Where AA.CodUsuario = #codUsuario
But it doesn't works because the Pos field has an other value. For example, it gives 2 instead 1.
I want to know how to get the row position number one by one ordered by a variable (because the field is a subquery).
It looks like you really want to do something like the below. I'm using CTEs because that makes it easier to read.
WITH BaseQuery AS
(
SELECT
U.CodUsuario
, PtsReputacion = (Select isnull(sum(Puntos),0) as Puntos
From USUARIO_RANKING_INTERES
Where USUARIO_RANKING_INTERES.CodUsuario = U.CodUsuario)
, USUARIO.CantIntentos as Intentos
, USUARIO.CantAciertos as Aciertos
, USUARIO.CantFallos as Fallos
, isnull(USUARIO.PG,0) as PG
, isnull(USUARIO.PE,0) as PE
, isnull(USUARIO.PP,0) as PP
, isnull(USUARIO.TiempoTotal,0) as TiempoTotal
FROM USUARIO U
),
RNQuery AS
(
SELECT
*
, ROW_NUMBER() OVER (ORDER BY PtsReputacion DESC) AS Pos
FROM
BaseQuery
)
SELECT
#pos = Pos
, #ptsReputacion = isnull(AA.PtsReputacion,0)
FROM
RNQuery AS AA
WHERE
AA.CodUsuario = #codUsuario

TSQL Convert select statement to update with joins

I have the following select statement:
SELECT projectid,documentid,revisionno,configurationid,variable45,
ISNULL(Variable45, (SELECT TOP 1 variable45 FROM pivot_table WHERE documentid = t.documentid and projectid=t.projectid
and configurationid=t.configurationid and cast(revisionno as int) < cast(t.revisionno as int) AND Variable45 is NOT NULL
ORDER BY projectid desc,documentid desc ,revisionno desc,configurationid desc)) as NewCol
FROM pivot_table t;
I tried converting to an update stement the following way, but I get wrong records updates. Can anyone help me resolve my problem:
UPdate PIVOT_TABLE
set variable45 = ((SELECT TOP 1 variable45 FROM pivot_table t WHERE t.documentid = documentid and t.projectid=projectid
and t.configurationid=configurationid and cast(t.revisionno as int) < cast(revisionno as int) AND Variable45 is NOT NULL
ORDER BY revisionno desc)) where Variable45 is NULL;
DB: SQLExpress2008.
Please advise. Thank you.
OK I figured it out:
UPdate pt
set pt.variable45 = ((SELECT TOP 1 t.variable45 FROM pivot_table t WHERE
t.documentid = pt.documentid and t.projectid=pt.projectid and t.configurationid=pt.configurationid and cast(t.revisionno as int) < cast(pt.revisionno as int) AND t.variable45 is NOT NULL
ORDER BY revisionno desc)) from PIVOT_TABLE pt where pt.variable45 is NULL;

Can you use a SELECT INTO statement with a CTE that contains a UDF?

Can I do this:
With ZipCodeCTE as
{
select nvl(HH.GeoUSZip5 , **ZipCodeKeyLookUp**(HH.[CityName],HH.[StateName])) as TotalZipCode
from ODSDataArchive.archive.HHJob_Data_201202 HH
}
/* This Is a SELECT INTO statement that inserts
data into [Jobs].[dbo].[FactRPP]*/
SELECT [dbo].[FactJobsDaily].jobdid,
[dbo].[FactJobsDaily].DateKey,
[dbo].[FactJobsDaily].YearMonth,
[dbo].[FactJobsDaily].AccountKey,
[dbo].[FactJobsDaily].BridgeSocKey,
[dbo].[FactJobsDaily].HostSiteKey,
[dbo].[FactJobsDaily].JobClickedCount,
[dbo].[FactJobsDaily].JobResultsPageCount,
(select DZ.ZipCodeKey
from dimensions.dbo.DimZipCode DZ
where DZ.ZipCodeKey IN
(Select CAST(TotalZipCode AS INT)
from ZipCodeCTE))
INTO [Jobs].[dbo].[FactRPP]
from dbo.FactJobsDaily
inner join ODSDataArchive.archive.HHJob_Data_201202
on dbo.FactJobsDaily.JobDID = ODSDataArchive.archive.HHJob_Data_201202.DID
and dbo.FactJobsDaily.datekey = ODSDataArchive.archive.HHJob_Data_201202.datekey
inner join dimensions.dbo.Dimzipcode dzc
on ODSDataArchive.archive.HHJob_Data_201202.geoUSZip5 = dimensions.dbo.Dimzipcode.ZipCode
where [dbo].[FactJobsDaily].yearmonth= 201202
and [dbo].[FactJobsDaily].isactivekey = 1
-- and ODSDataArchive.archive.HHJob_Data_201202.geoUSZip5 <> ''
-- and ODSDataArchive.archive.HHJob_Data_201202.geoUSZip5 IS NOT NULL
and ODSDataArchive.archive.HHJob_Data_201202.status = 0
and ODSDataArchive.archive.HHJob_Data_201202.CountryName = 'US'
order by [dbo].[FactJobsDaily].jobdid;
Because the CTE translates into a regular query the short answer is yes.

Get index of row within a group?

I have two tables:
Unit:
UnitId int PK
Title varchar
UnitOption:
UnitOptionId int PK
UnitId int FK
Title varchar
Quote:
QuoteId int PK
UnitOptionId int FK
Title varchar
I want to create a scalar UDF that takes a QuoteId param and returns a varchar that contains the following description (pseudu):
Quote.Title + '-' + Unit.Title + '-' + Unit.UnitId +
/* Here is where my question is:
If there are more than 1 UnitOption under this Unit, then
return '-' + the UnitOption number under this Unit
(i.e.) if under this Unit, there are 3 UnitOption with IDs 13, 17, 55
under the unit, and the current Quote.UnitOptionId is the 17 one,
it should return 2.
Which means I want to retrieve an ID of this row in the group.
Else
return ''
*/
If you're using SQL 2005 or later and I've interpreted your question correctly, you should be able to adapt the following into your function.
WITH [UnitExt] AS
(
SELECT
[Unit].[UnitId],
[Unit].[Title],
COUNT(*) AS [Count]
FROM [Unit]
INNER JOIN [UnitOption] ON [UnitOption].[UnitId] = [Unit].[UnitId]
GROUP BY
[Unit].[UnitId],
[Unit].[Title]
)
SELECT
[Quote].[Title] + '-' + [UnitExt].[Title] + '-' + [UnitExt].[UnitId] +
CASE
WHEN [UnitExt].[Count] > 1 THEN '-' +
CAST([UnitOption].[UnitOptionId] AS varchar(max))
ELSE ''
END
FROM [Quote]
INNER JOIN [UnitOption] ON [UnitOption].[UnitOptionId] =
[Quote].[UnitOptionId]
INNER JOIN [UnitExt] ON [UnitExt].[UnitId] = [UnitOption].[UnitId]
WHERE [Quote].[QuoteId] = #QuoteId
Something like this should do it.
SELECT DISTINCT Quote.Title +
' - ' + Unit.Title +
' - ' + Unit.UnitId +
CASE
WHEN COUNT(*) OVER(PARTITION BY Quote.Id) > 0
THEN
' - ' + CAST(ROW_NUMBER() OVER (PARTITION BY Quote.Id ORDER BY Quote.UnitOptionId) AS varchar)
ELSE
''
END
FROM Quote
JOIN UnitOption ON UnitOption.Id = Quote.UnitOptionId
JOIN Unit ON Unit.Id = UnitOption.UnitId
WHERE Quote.Id = #QuoteId
CREATE FUNCTION ufnGetDescription
(#QuoteID INT)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #RetVal VARCHAR(MAX);
WITH CurRow
AS (SELECT quote.title + '- ' + unit.title AS start,
u.unitid,
quoteid,
uo.unitoptionid
FROM quote
INNER JOIN unitoption uo
ON quote.unitoptionid = uo.unitoptionid
INNER JOIN unit
ON uo.unitid = unit.unitid
WHERE quote.quoteid = #QuoteID),
AllUnits
AS (SELECT u.unitid,
uo.unitoptionid,
Row_number()
OVER(PARTITION BY u.unitid ORDER BY uo.unitoptionid) AS NUMBER,
Count(* )
OVER(PARTITION BY u.unitid ) AS cntUnits
FROM unit
INNER JOIN unionoption uo
ON unit.unitid = uo.unitid
WHERE u.unitid IN (SELECT unitid
FROM CurRow))
SELECT #RetVal = CASE
WHEN a.cntUnits = 1 THEN ''
ELSE r.start + '-' + Cast(NUMBER AS VARCHAR(max))
END
FROM AllUnits a
INNER JOIN CurRow r
ON a.unitoptionid = r.unitoptionid
RETURN #RetVal
END