TSQL turning these multiple CASE queries into one query - sql-server

I have the following CASE queries that return 1 if they find anything, and 0 otherwise. I would like to turn these into a single query that returns 1 if any of them are true, or 0 otherwise. How can I acomplish this?
SELECT CASE WHEN count(PLACE.CODE) > 0 THEN 1 ELSE 0 END
FROM PLACE
WHERE STYLE = 'RED'
AND RULES = 'NO'
SELECT CASE WHEN count(GARDEN.AREA) > 0 THEN 1 ELSE 0 END
FROM GARDEN
WHERE PLACE = 'GROUND'
AND MAZE = '1'
SELECT CASE WHEN count(place_area.AVAILABLE_AREA) > 0 THEN 1 ELSE 0 END
FROM PLACE_AREA as place_area
INNER JOIN USED_PLACE as used_place
ON used_place.COLOR = 'RED'
AND used_place.MAKE = 'INDUSTRY'
WHERE place_area.CODE = 'FLOOR'
AND place_area.DANCE = '0'

If I understand you correctly, you can union all the result and calculate the sum, if sum > 0 then there was at least one 1
Select Case When Sum(x.col) > 0 THEN 1 ELSE 0 END from
(
SELECT CASE WHEN count(PLACE.CODE) > 0 THEN 1 ELSE 0 END as col
FROM PLACE
WHERE STYLE = 'RED'
AND RULES = 'NO'
Union All
SELECT CASE WHEN count(GARDEN.AREA) > 0 THEN 1 ELSE 0 END as col
FROM GARDEN
WHERE PLACE = 'GROUND'
AND MAZE = '1'
Union All
SELECT CASE WHEN count(place_area.AVAILABLE_AREA) > 0 THEN 1 ELSE 0 END as col
FROM PLACE_AREA as place_area
INNER JOIN USED_PLACE as used_place
ON used_place.COLOR = 'RED'
AND used_place.MAKE = 'INDUSTRY'
WHERE place_area.CODE = 'FLOOR'
AND place_area.DANCE = '0'
) x

SELECT
CASE
WHEN
EXISTS(
SELECT TOP 1 1
FROM PLACE
WHERE STYLE = 'RED'
AND RULES = 'NO'
AND count(PLACE.CODE) > 0
)
OR EXISTS (
SELECT TOP 1 1
FROM GARDEN
WHERE PLACE = 'GROUND'
AND MAZE = '1'
AND count(GARDEN.AREA) > 0
)
OR EXISTS (
SELECT TOP 1 1
FROM PLACE_AREA as place_area
INNER JOIN USED_PLACE as used_place
ON used_place.COLOR = 'RED'
AND used_place.MAKE = 'INDUSTRY'
WHERE place_area.CODE = 'FLOOR'
AND place_area.DANCE = '0'
AND count(place_area.AVAILABLE_AREA) > 0
)
THEN 1
ELSE 0
END

Related

MERGE statement updates even if the data is not updated

I have a merge statement in which I'd like to update my table rows in case any of the columns have a different value. But it seems like even though most of the rows in the source table have remained intact, the MERGE statement performs an UPDATE on at least counts what it does an UPDATE.
DECLARE #SummaryOfChanges TABLE(Change VARCHAR(50));
MERGE MyTarget AS TARGET
USING MySource AS SOURCE
ON (SOURCE.customeridHash = TARGET.Id)
WHEN MATCHED AND (TARGET.IsCompany <> SOURCE.company
OR TARGET.Gender <> SOURCE.gender
OR TARGET.BirthDate <> CONVERT(DATE, SOURCE.dateofbirth)
OR TARGET.ZipCode <> SOURCE.ZipCode
OR TARGET.City <> SOURCE.City
OR TARGET.WantsEmail <> (CASE WHEN SOURCE.noemail = 0 THEN 1 ELSE 0 END)
OR TARGET.WantsSMS <> (CASE WHEN SOURCE.nosms = 0 THEN 1 ELSE 0 END)
OR TARGET.WantsDM <> (CASE WHEN SOURCE.nodirectmarketing = 0 THEN 1 ELSE 0 END)
OR TARGET.WantsTM <> (CASE WHEN SOURCE.notelemarketing = 0 THEN 1 ELSE 0 END)
OR TARGET.HasEmail <> SOURCE.HasEmail
OR TARGET.HasMobilePhoneNumber <> SOURCE.HasMobilePhoneNumber
OR TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber
OR TARGET.Created <> SOURCE.Created
OR TARGET.Updated <> SOURCE.changed)
THEN
UPDATE SET TARGET.IsCompany = SOURCE.company,
TARGET.Gender = SOURCE.gender,
TARGET.BirthDate = CONVERT(DATE, SOURCE.dateofbirth),
TARGET.ZipCode = SOURCE.ZipCode,
TARGET.City = SOURCE.City,
TARGET.WantsEmail = (CASE WHEN SOURCE.noemail = 0 THEN 1 ELSE 0 END),
TARGET.WantsSMS = (CASE WHEN SOURCE.nosms = 0 THEN 1 ELSE 0 END),
TARGET.WantsDM = (CASE WHEN SOURCE.nodirectmarketing = 0 THEN 1 ELSE 0 END),
TARGET.WantsTM = (CASE WHEN SOURCE.notelemarketing = 0 THEN 1 ELSE 0 END),
TARGET.HasEmail = SOURCE.HasEmail,
TARGET.HasMobilePhoneNumber = SOURCE.HasMobilePhoneNumber,
TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber,
TARGET.Created = SOURCE.Created,
TARGET.Updated = SOURCE.changed
WHEN NOT MATCHED BY TARGET THEN
INSERT (
Id,
IsCompany,
Gender,
BirthDate,
ZipCode,
City,
WantsEmail,
WantsSMS,
WantsDM,
WantsTM,
HasEmail,
HasMobilePhoneNumber,
HasPhoneNumber,
Created,
Updated
)
VALUES (
SOURCE.customeridHash,
SOURCE.company,
SOURCE.gender,
CONVERT(DATE, SOURCE.dateofbirth),
SOURCE.ZipCode,
SOURCE.City,
(CASE WHEN SOURCE.noemail = 0 THEN 1 ELSE 0 END),
(CASE WHEN SOURCE.nosms = 0 THEN 1 ELSE 0 END),
(CASE WHEN SOURCE.nodirectmarketing = 0 THEN 1 ELSE 0 END),
(CASE WHEN SOURCE.notelemarketing = 0 THEN 1 ELSE 0 END),
SOURCE.HasEmail,
SOURCE.HasMobilePhoneNumber,
SOURCE.HasPhoneNumber,
SOURCE.Created,
SOURCE.changed
)
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT $action INTO #SummaryOfChanges;
SELECT Change, COUNT(*) CountPerChange
FROM #SummaryOfChanges
GROUP BY Change;
I do some bookkeeping at the end of the update (the final SELECT) and it seems like almost all the rows that are not new, were updated. Is this a common behavior or is there really a value amongst my <> comparison for WHEN MATCHED AND... that is updated?
Update: As suggested by one of the comments, I wrote the following test to check whether my conditions trigger an update or not:
-- TEST MERGE
select count(*)
from MyTarget TARGET join MySource SOURCE on TARGET.Id=SOURCE.customeridHash
where TARGET.IsCompany <> SOURCE.company
OR TARGET.Gender <> SOURCE.gender
OR TARGET.BirthDate <> CONVERT(DATE, SOURCE.dateofbirth)
OR TARGET.ZipCode <> SOURCE.ZipCode
OR TARGET.City <> SOURCE.City
OR TARGET.WantsEmail <> (CASE WHEN SOURCE.noemail = 0 THEN 1 ELSE 0 END)
OR TARGET.WantsSMS <> (CASE WHEN SOURCE.nosms = 0 THEN 1 ELSE 0 END)
OR TARGET.WantsDM <> (CASE WHEN SOURCE.nodirectmarketing = 0 THEN 1 ELSE 0 END)
OR TARGET.WantsTM <> (CASE WHEN SOURCE.notelemarketing = 0 THEN 1 ELSE 0 END)
OR TARGET.HasEmail <> SOURCE.HasEmail
OR TARGET.HasMobilePhoneNumber <> SOURCE.HasMobilePhoneNumber
OR TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber
OR TARGET.Created <> SOURCE.Created
OR TARGET.Updated <> SOURCE.changed;
I realised that this query returns the same number of updates. So it is somehow more about the condition that the MERGE statement. But I wonder how they trigger updates.
I think I found my own mistake, in the conditions I write:
OR TARGET.HasPhoneNumber = SOURCE.HasPhoneNumber
Which almost always renders true!

Select with Case - amalgamating results into single record

I have a query as follows
SELECT
FGB.TEMPLATE_DETAILS_REF, FGB.TEMPLATE_STRUCTURE_REF, FGB.DFEE_ELEMENT,
CASE
WHEN Condition = 'A' THEN SUM(FGS.Weighted) END AS CondA,
CASE
WHEN Condition = 'B' THEN SUM(FGS.Weighted) END AS CondB,
CASE
WHEN Condition = 'C' THEN SUM(FGS.Weighted) END AS CondC,
CASE
WHEN Condition = 'D' THEN SUM(FGS.Weighted) END AS CondD
FROM FGBlockSummary AS FGB INNER JOIN
FGSurveyItem AS FGS ON FGB.TEMPLATE_DETAILS_REF = FGS.TEMPLATE_DETAILS_REF AND FGB.TEMPLATE_STRUCTURE_REF = FGS.TEMPLATE_STRUCTURE_REF AND
FGB.DFEE_ELEMENT = FGS.DFEE_ELEMENT
GROUP BY FGB.TEMPLATE_DETAILS_REF, FGB.TEMPLATE_STRUCTURE_REF, FGB.DFEE_ELEMENT, FGS.Condition
which produces results as follows:
16 109 Ceilings NULL 14101.47 NULL NULL
16 109 Ceilings NULL NULL 227.68 NULL
How can I amalgamate the results into a single row eg
16 109 Ceilings NULL 14101.47 227.68 NULL
Thanks
Is this what you're looking for?
I moved the SUM outside of the CASEs and eliminated FGS.Condition from the GROUP BY. It'll have the side-effect of changing your NULL values to '0', but that might be tolerable?
SELECT
FGB.TEMPLATE_DETAILS_REF
,FGB.TEMPLATE_STRUCTURE_REF
,FGB.DFEE_ELEMENT
,CondA = SUM(
CASE
WHEN FGS.Condition = 'A' THEN FGS.Weighted
ELSE 0
END)
,CondB = SUM(
CASE
WHEN FGS.Condition = 'B' THEN FGS.Weighted
ELSE 0
END)
,CondC = SUM(
CASE
WHEN FGS.Condition = 'C' THEN FGS.Weighted
ELSE 0
END)
,CondD = SUM(
CASE
WHEN FGS.Condition = 'D' THEN FGS.Weighted
ELSE 0
END)
FROM
FGBlockSummary AS FGB
INNER JOIN
FGSurveyItem AS FGS
ON
FGB.TEMPLATE_DETAILS_REF = FGS.TEMPLATE_DETAILS_REF
AND FGB.TEMPLATE_STRUCTURE_REF = FGS.TEMPLATE_STRUCTURE_REF
AND FGB.DFEE_ELEMENT = FGS.DFEE_ELEMENT
GROUP BY
FGB.TEMPLATE_DETAILS_REF
,FGB.TEMPLATE_STRUCTURE_REF
,FGB.DFEE_ELEMENT;

what should i use if i want to update my record if a certain condition its true

i want to update my records, if the day of the last payment of the client its greater than 100;
update clients set ind_mo = 2,
ind_pay=2
if its less than 100;
update clients set ind_mo = 1,
ind_pay = 1
if the the own of the client its = 0
update clients set ind_mo = 1,
ind_pay = 1
i already tried this but it does not update my record if the own its 0
if (datediff(day,((select top 1 fec_ven from
cxc_cuedoc cue inner join cxc_cliente cli
on cli.cod_cli = cue.cod_cli where sal_doc !=0 and cue.tip_doc = '010' and num_doc=cue.num_doc)),getdate())) > 110
update cxc_cliente
set ind_mora ='2',
IND_JURIDICO = '2';
else
update cxc_cliente
set ind_mora = '1',
ind_juridico ='1'
UPDATE Cli
SET Cli.ind_mo = CASE WHEN DATEDIFF(DAY , fec_ven , GETDATE()) > 100
THEN 2 ELSE 1 END
,Cli.ind_pay = CASE WHEN DATEDIFF(DAY , fec_ven , GETDATE()) > 100
THEN 2 ELSE 1 END
from cxc_cuedoc cue
inner join cxc_cliente cli on cli.cod_cli = cue.cod_cli
and cli.num_doc = cue.num_doc
where sal_doc != 0
and cue.tip_doc = '010'
Or if you are only interested in the last row, maybe something like this...
WITH X AS (
SELECT ind_mo , ind_pay , fec_ven
, ROW_NUMBER() OVER (PARTITION BY cli.cod_cli ORDER BY fec_ven DESC) rn
FROM cxc_cuedoc cue
inner join cxc_cliente cli on cli.cod_cli = cue.cod_cli
and cli.num_doc = cue.num_doc
where sal_doc !=0
and cue.tip_doc = '010'
)
UPDATE x
SET x.ind_mo = CASE WHEN DATEDIFF(DAY , x.fec_ven , GETDATE()) > 100
THEN 2 ELSE 1 END
,x.ind_pay = CASE WHEN DATEDIFF(DAY , x.fec_ven , GETDATE()) > 100
THEN 2 ELSE 1 END
WHERE x.rn = 1

How to optimise a stored procedure that is too slow? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
My stored procedure is taking around 1 minute 45 seconds, how can I optimize it? I tried couple of things like creating temp table before doing the insert.
I have Estimated Execution Plan but I don't know how to upload it.
This is part of my stored procedure which is taking longer time and Query Cost is 53%.
SELECT Distinct
BackupCTE.[InstanceName]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.EnvironmentType = 0 THEN '-1' Else CONVERT(VARCHAR,BackupCTE.EnvironmentType) END AS EnvironmentType
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.InstanceStatus = 0 THEN '-1' Else CONVERT(VARCHAR,BackupCTE.InstanceStatus) END AS [InstanceStatus]
,BackupCTE.[BackupShare]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.DatabaseOwner = 0 THEN '-1'
WHEN ISNULL(BackupCTE.IsMirroringEnabled,0) = 0 AND BackupCTE.DatabaseOwner NOT IN ('SA') AND BackupCTE.DatabaseStatus = 'Normal' AND BackupCTE.DatabaseReadOnly = 0
AND ISNULL(BackupCTE.IsDatabaseSnapshot,0) = 0 THEN '0'
ELSE '1' END AS DatabaseOwner
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.DBRecoveryModel = 0 THEN '-1'
WHEN BackupCTE.DatabaseStatus = 'Normal' AND BackupCTE.DatabaseName NOT IN ('master', 'msdb', 'IHC_DBA','distribution','ReportServerTempDB','NavicareReporting','ReportServer') AND
BackupCTE.RecoveryModel NOT IN ('Full','BulkLogged') THEN '0'
ELSE '1'
END AS [DBRecoveryModel]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.AutoShrink = 0 THEN '-1'
ELSE CONVERT(VARCHAR, BackupCTE.[AutoShrink]) END AS [AutoShrink]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.AutoClose = 0 THEN '-1' Else CONVERT(VARCHAR,BackupCTE.[AutoClose]) END AS [AutoClose]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.BackupCompression = 0 THEN '-1'
WHEN BackupCTE.[BackupCompression] = 0 THEN '0'
Else '1' END AS [BackupCompression]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.XPCmdShell = 0 THEN '-1'
WHEN CONVERT(VARCHAR,BackupCTE.[XPCmdShell]) = 0 THEN '1'
Else '0' END AS [XPCmdShell]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.EncryptionEnabled = 0 THEN '-1' Else CONVERT(VARCHAR,BackupCTE.[EncryptionEnabled]) END AS [EncryptionEnabled]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.IsIdera = 0 THEN '-1' Else CONVERT(VARCHAR,BackupCTE.[IsIdera]) END AS [IsIdera]
,[HoursRetentionShare]
,[HoursSinceLastFullBackup]
,[HoursSinceLastDiffBackup]
,[HoursSinceLastLogBackup]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.ExceededBkpTimeFrame = 0 THEN '-1' Else BackupCTE.ExceededBkpTimeFrame
END AS ExceededBkpTimeFrame
,BackupType
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.[Primary] = 0 THEN '-1' Else BackupCTE.[Primary] END AS [Primary]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.[Secondary] = 0 THEN '-1' Else BackupCTE.[Secondary] END AS [Secondary]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.[LockPages] = 0 THEN '-1'
Else CONVERT(varchar,BackupCTE.[LockPages]) END AS [LockPages]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.[SADisabled] = 0 THEN '-1'
WHEN CONVERT(varchar,BackupCTE.[SADisabled]) = 0 AND BackupCTE.VersionName like 'Microsoft SQL Server 2000 %' THEN '1'
ELSE CONVERT(varchar,BackupCTE.[SADisabled])
END AS [SADisabled]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.ServiceAccount = 0 THEN '-1'
WHEN StdServiceAccount.IsValid = 1
OR BackupCTE.ServiceAccount IN ('CO\lpsqldbadmin','lpsqldbadmin#CO.IHC.COM')
THEN '1'
ELSE '0' END AS ServiceAccount
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.[ServicePackFlag] = 0 THEN '-1' Else BackupCTE.[ServicePack] END AS [ServicePack]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.[MaxMemory] = 0 THEN '-1' Else BackupCTE.[MaxMemory] END AS [MaxMemory]
,[JobName]
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.[JobOwner] = 0 THEN '-1'
WHEN BackupCTE.JobOwner NOT IN ('SA') AND JobEnabled = 1 AND DELETED IS NULL THEN '0'
ELSE '1' END AS JobOwner
,[JobEnabled]
,CASE WHEN BackupCTE.EnvironmentType = 'PROD' AND BackupCTE.[Primary] NOT IN ('Tamie Jensen', 'Chase Mahony','Megna Musapeta','Aaron Uppencamp') THEN '0'
WHEN BackupCTE.EnvironmentType = 'STBY' AND BackupCTE.[Primary] NOT IN ('Tamie Jensen', 'Chase Mahony','Megna Musapeta','Aaron Uppencamp') THEN '0'
ELSE '1' END AS IsNonPrimary
,CASE WHEN BackupCTE.EnvironmentType = 'PROD' AND BackupCTE.[Secondary] IN ('NONE') THEN '0'
WHEN BackupCTE.EnvironmentType = 'STBY' AND BackupCTE.[Secondary] IN ('NONE') THEN '0'
ELSE '1' END AS IsNonSecondary
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.[MaxMemory] = 0 THEN '-1'
WHEN BackupCTE.[MaxMemory]%8 = 0 THEN '1'
ELSE '0' END AS FlagMemory
,CASE WHEN BackupCTE.JobName NOT LIKE '%Insure%'
THEN
CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.MaintenanceJob = 0 THEN '-1'
WHEN JobSchMultiplier < 0 THEN '1' --One Time Job. No Need To Flag
WHEN DATEDIFF(HH, BackupCTE.JobRunDate, GETDATE()) > 24*JobSchMultiplier THEN '0'
ELSE '1'
END
ELSE '1' END AS MaintenanceJob
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.ServicePackFlag = 0 THEN '-1'
WHEN LTRIM(RTRIM(SUBSTRING(PatchingStds.ServicePack,3, LEN(PatchingStds.ServicePack)-2))) > ISNULL(LTRIM(RTRIM(SUBSTRING(InstanceSQLDTl.ServicePack,3,
LEN(InstanceSQLDTl.ServicePack)-2))),0) THEN '0'
WHEN LTRIM(RTRIM(SUBSTRING(VersionName,CHARINDEX('-',VersionName )+1,abs(CASE WHEN CHARINDEX('(',VersionName ) > 0 THEN CHARINDEX('(',VersionName )-CHARINDEX('-',VersionName) ELSE len(VersionName)-CHARINDEX('-',VersionName) end)))) <> LTRIM(RTRIM(PatchingStds.SQLBuild)) THEN '2'
ELSE '1' END AS ServicePackFlag
,VersionName
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.SAViolations = 0 THEN '-1'
WHEN LoginName Not IN ('CO\DBA Group','CO\DBAdmin') AND SYSAdmin = 1 OR SecurityAdmin = 1 OR ServerAdmin = 1 OR SetupAdmin = 1 OR ProcessAdmin = 1 OR DiskAdmin = 1
OR DBCreator = 1 OR BulkAdmin = 1 THEN '0'
ELSE '1' END AS SAViolations
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.IsBackupShare = 0 THEN '-1'
WHEN NOT (BackupCTE.[BackupShare] LIKE '\\CO.IHC.COM%' OR BackupCTE.[BackupShare] LIKE '\\CO-LP-SQL1%' OR BackupCTE.[BackupShare] LIKE '\\CO-LP-SQL2%'
OR BackupCTE.[BackupShare] LIKE '\\CO-TX-VAULT2%' OR BackupCTE.[BackupShare] LIKE '\\co-tx-vpdsfile2\txPDSsqlBackups%' AND BackupCTE.[BackupShare] NOT LIKE '%Test') OR BackupCTE.[BackupShare] = 'NONE LISTED' THEN '0'
ELSE '1' END AS IsBackupShare
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.Tempdb_DataFileCount = 0 THEN '-1'
WHEN TEMPDBFileCount.Tempdb_DataFileCount >= 8 OR TEMPDBFileCount.Tempdb_DataFileCount > TEMPDBFileCount.OptimalTempdbFilecount THEN '1'
WHEN TEMPDBFileCount.OptimalTempdbFilecount > TEMPDBFileCount.Tempdb_DataFileCount THEN '0'
ELSE '1'END AS Tempdb_DataFileCount
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.DataAutoGrow = 0 THEN '-1' ELSE BackupCTE.DataAutoGrow END AS DataAutoGrow
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.LogAutoGrow = 0 THEN '-1' ELSE BackupCTE.LogAutoGrow END AS LogAutoGrow
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.MaintVersion = 0 THEN '-1' ELSE BackupCTE.MaintVersion END AS MaintVersion
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.MaintVersion = 0 THEN '-1'
WHEN BackupCTE.MaintVersion = 2.02 OR BackupCTE.MaintVersion = 2.03 THEN '1'
ELSE '0' END AS FlagMaintVersion
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.DBCompatibilityLevel = 0 THEN '-1'
WHEN BackupCTE.DBCompatibilityLevel < 90 THEN '0'
ELSE '1' END AS DBCompatibilityLevel
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.FlagVersionName = 0 THEN '-1'
WHEN NOT (BackupCTE.VersionName LIKE 'Microsoft SQL Server 2005%' OR BackupCTE.VersionName LIKE 'Microsoft SQL Server 2000%') THEN '1'
ELSE '0' END AS FlagVersionName
,CASE WHEN DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL AND ComplianceReportExceptions.VLFCount = 0 THEN '-1'
ELSE BackupCTE.VLFCount END AS VLFCount
Into #FinalData
FROM [DBAPP].InstanceSQLDtl
LEFT JOIN #BackupCTE BackupCTE ON InstanceSQLDtl.InstanceID = BackupCTE.InstanceID
LEFT JOIN [DBAPP].[SQLPatchingStandards] PatchingStds ON LTRIM(RTRIM(LEFT(VersionName, CHARINDEX('-', VersionName)-1))) = LTRIM(RTRIM(LEFT
(PatchingStds.SQLVersion,CHARINDEX('-',PatchingStds.SQLVersion)-1)))
LEFT JOIN [DBAPP].[ComplianceReportExceptions] ON ComplianceReportExceptions.InstanceName = BackupCTE.InstanceName
LEFT JOIN [DBAPP].[TEMPDBFileCount] ON InstanceSQLDtl.InstanceID = [TEMPDBFileCount].InstanceID AND Type_DESC = 'ROWS'
LEFT JOIN DBO.fnGetServiceNames() StdServiceAccount ON BackupCTE.InstanceID = StdServiceAccount.InstanceID
Where BackupCTE.[InstanceName] IS NOT NULL
ORDER BY [InstanceName]
That much string manipulation and CASE statements are just always going to be slow. Maybe you can run it as a nightly batch process into a datamart? Otherwise, here are a few tips:
Since many of your CASE statements are testing for ...InstanceName IS NULL, you can split the query in half and use UNION ALL to join together the records where it is and is not null (see example). This will remove a bunch of CASE checks.
Don't use WHERE IN('SA') if there's only one item, use not-equal (<>) instead.
If at all possible, avoid doing string manipulation in a JOIN condition (...PatchingStds ON LTRIM(RTRIM(LEFT(VersionName...). Try to store those fields somewhere, either in a dedicated column or as persisted, computed columns. That way you can put in index on that field to make the join much faster.
Have indexes on the join fields where possible, subject to many factors, but mostly just don't have too many indexes on a single table because that will slow down INSERT statements.
SELECT DISTINCT
BackupCTE.[InstanceName]
, EnvironmentType = CASE WHEN ComplianceReportExceptions.EnvironmentType = 0 THEN '-1' ELSE CONVERT(VARCHAR, BackupCTE.EnvironmentType) END
, [InstanceStatus] = CASE WHEN ComplianceReportExceptions.InstanceStatus = 0 THEN '-1' ELSE CONVERT(VARCHAR,BackupCTE.InstanceStatus) END
, BackupCTE.[BackupShare]
, DatabaseOwner =
CASE WHEN ComplianceReportExceptions.DatabaseOwner = 0 THEN '-1'
WHEN ISNULL(BackupCTE.IsMirroringEnabled,0) = 0
AND BackupCTE.DatabaseOwner <> 'SA'
AND BackupCTE.DatabaseStatus = 'Normal'
AND BackupCTE.DatabaseReadOnly = 0
AND ISNULL(BackupCTE.IsDatabaseSnapshot,0) = 0
THEN '0'
ELSE '1'
END
-- Etc...
INTO #FinalData
FROM [DBAPP].InstanceSQLDtl
LEFT JOIN #BackupCTE BackupCTE ON InstanceSQLDtl.InstanceID = BackupCTE.InstanceID
LEFT JOIN [DBAPP].[SQLPatchingStandards] PatchingStds ON LTRIM(RTRIM(LEFT(VersionName, CHARINDEX('-', VersionName)-1))) = LTRIM(RTRIM(LEFT
(PatchingStds.SQLVersion,CHARINDEX('-',PatchingStds.SQLVersion)-1)))
LEFT JOIN [DBAPP].[ComplianceReportExceptions] ON ComplianceReportExceptions.InstanceName = BackupCTE.InstanceName
LEFT JOIN [DBAPP].[TEMPDBFileCount] ON InstanceSQLDtl.InstanceID = [TEMPDBFileCount].InstanceID AND Type_DESC = 'ROWS'
LEFT JOIN DBO.fnGetServiceNames() StdServiceAccount ON BackupCTE.InstanceID = StdServiceAccount.InstanceID
WHERE BackupCTE.[InstanceName] IS NOT NULL
AND DBAPP.ComplianceReportExceptions.InstanceName IS NOT NULL
--****************
UNION ALL
--****************
SELECT DISTINCT
BackupCTE.[InstanceName]
, EnvironmentType = CONVERT(VARCHAR,BackupCTE.EnvironmentType)
, [InstanceStatus] = CONVERT(VARCHAR,BackupCTE.InstanceStatus)
, BackupCTE.[BackupShare]
, DatabaseOwner =
CASE
WHEN ISNULL(BackupCTE.IsMirroringEnabled,0) = 0
AND BackupCTE.DatabaseOwner <> 'SA'
AND BackupCTE.DatabaseStatus = 'Normal'
AND BackupCTE.DatabaseReadOnly = 0
AND ISNULL(BackupCTE.IsDatabaseSnapshot,0) = 0
THEN '0'
ELSE '1'
END
-- Etc...
INTO #FinalData
FROM [DBAPP].InstanceSQLDtl
LEFT JOIN #BackupCTE BackupCTE ON InstanceSQLDtl.InstanceID = BackupCTE.InstanceID
LEFT JOIN [DBAPP].[SQLPatchingStandards] PatchingStds ON LTRIM(RTRIM(LEFT(VersionName, CHARINDEX('-', VersionName)-1))) = LTRIM(RTRIM(LEFT
(PatchingStds.SQLVersion,CHARINDEX('-',PatchingStds.SQLVersion)-1)))
LEFT JOIN [DBAPP].[ComplianceReportExceptions] ON ComplianceReportExceptions.InstanceName = BackupCTE.InstanceName
LEFT JOIN [DBAPP].[TEMPDBFileCount] ON InstanceSQLDtl.InstanceID = [TEMPDBFileCount].InstanceID AND Type_DESC = 'ROWS'
LEFT JOIN DBO.fnGetServiceNames() StdServiceAccount ON BackupCTE.InstanceID = StdServiceAccount.InstanceID
WHERE BackupCTE.[InstanceName] IS NOT NULL
AND DBAPP.ComplianceReportExceptions.InstanceName IS NULL
--****************
ORDER BY [InstanceName]
Below are the possibilities which causes to degrade the performance of an query,
Do not convert colum value at on clause instead of this create a separate colum and pre-populated the conversion, if you use conversion
it prohibit using indexes to search records in table.
Use with(nolock)
Distinct & order by are costly operations to the query , if you don’t required remove it from query.

How to use conditional columns values in the same select statement?

I have something like
(COMPLEX_EXPRESSION_N stands for a long subquery)
select
ID_Operation,
FirstCheck = CASE WHEN (COMPLEX_EXPRESSION_1)= 0 then 0 else 1 end,
SecondCheck = CASE WHEN (COMPLEX_EXPRESSION_2)= 0 then 0 else 1 end,
ThirdCheck = CASE WHEN (COMPLEX_EXPRESSION_3)= 0 then 0 else 1 end,
AllChecksOk = Case WHEN
(FirstCheck + SecondCheck + Third CHeck = 3)
Then 'OK' Else 'No' End
from
AllOperationsTable
Is it possible to use FirstCheck, SecondCheck, ThirdCheck as I did in the AllChecksOk line?
I am not concerned about performance, this is something that is manually run once a day on a very small number of records, I just want to avoid to create views, tables or temporary tables and keep all in a single select statement.
As an altenrative I can do this, but it makes the query less readable (as I need to write twice every complex expression):
select
ID_Operation,
FirstCheck = CASE WHEN (COMPLEX_EXPRESSION_1)= 0 then 0 else 1 end,
SecondCheck = CASE WHEN (COMPLEX_EXPRESSION_2)= 0 then 0 else 1 end,
ThirdCheck = CASE WHEN (COMPLEX_EXPRESSION_3)= 0 then 0 else 1 end,
AllChecksOk = Case WHEN
(COMPLEX_EXPRESSION_1+ COMPLEX_EXPRESSION_2+
COMPLEX_EXPRESSION_3CHeck = 3) Then 'OK' Else 'No' End
from
AllOperationsTable
You can't reference a column alias in the select but you can use a CTE as below.
;WITH CTE AS
(
select
ID_Operation,
FirstCheck = CASE WHEN (COMPLEX_EXPRESSION_1)= 0 then 0 else 1 end,
SecondCheck = CASE WHEN (COMPLEX_EXPRESSION_2)= 0 then 0 else 1 end,
ThirdCheck = CASE WHEN (COMPLEX_EXPRESSION_3)= 0 then 0 else 1 end
from
AllOperationsTable
)
SELECT *,
AllChecksOk = Case WHEN
(COMPLEX_EXPRESSION_1+ COMPLEX_EXPRESSION_2+
COMPLEX_EXPRESSION_3CHeck = 3) Then 'OK' Else 'No' End
FROM CTE
You can also use CROSS APPLY to define the 3 column aliases then reference them in the main SELECT list as in this example.
Below is a derived table solution
SELECT
T.ID_Operation,
FirstCheck = CASE WHEN T.Expr1 = 0 THEN 0 ELSE 1 END,
SecondCheck = CASE WHEN T.Expr2 = 0 THEN 0 ELSE 1 END,
ThirdCheck = CASE WHEN T.Expr3 = 0 THEN 0 ELSE 1 END,
AllChecksOk = CASE WHEN T.Expr1 + T.Expr2 + T.Expr3 = 3 THEN 'OK' ELSE 'No' END
FROM
(
SELECT
ID_Operation,
Expr1 = (COMPLEX_EXPRESSION_1),
Expr2 = (COMPLEX_EXPRESSION_2),
Expr3 = (COMPLEX_EXPRESSION_3)
FROM
AllOperationsTable
) T
Personally, I find using CTE or derived tables a bit confusing for this purpose, as you have to nest things one level and think about the nesting impliciations. A much simpler approach (at least in my opinion) is to use APPLY (or standard SQL LATERAL in other RDBMS) to generate column expression aliases:
SELECT
ID_Operation,
FirstCheck,
SecondCheck,
ThirdCheck,
AllChecksOk = CASE
WHEN FirstCheck + SecondCheck + ThirdCheck = 3 THEN 'OK' ELSE 'NO'
END
FROM
AllOperationsTable
CROSS APPLY (
SELECT
FirstCheck = CASE WHEN COMPLEX_EXPRESSION_1 = 0 THEN 0 ELSE 1 END,
SecondCheck = CASE WHEN COMPLEX_EXPRESSION_1 = 0 THEN 0 ELSE 1 END,
ThirdCheck = CASE WHEN COMPLEX_EXPRESSION_1 = 0 THEN 0 ELSE 1 END
) t

Resources