SQL get fields which are null/empty for each record returned - sql

I have the below query which I'm using to retrieve records which have at least one of the following columns set as NULL or '':
MainImage
Summary
Description
DECLARE #missingFields varchar(100)
SET #missingFields = ''
SELECT
c.[UnitReference] as 'UnitRef',
t.[NodeName] as 'Property',
#missingFields as 'Field/s missing'
FROM [DetailPage] d
INNER JOIN [CRM] c
ON d.ItemID = c.ItemID
INNER JOIN
[Tree] t
ON d.[ID] = t.[ID]
WHERE (ISNULL(d.MainImage, '') = '' OR ISNULL(d.Summary,'') = '' OR ISNULL(d.[Description],'') = '')
AND c.[IsListed] = 1 AND c.[IsMarketed] = 1
This returns the data I want however I also need to build up a string which lists which of the columns is null or empty for the returned record, e.g. "Main Image is empty, Description is empty" when a record has empty MainImage and Description columns.
I've tried:
#missingFields = CASE WHEN ISNULL(MainImage, '') = '' THEN 'Main image is null' ELSE '' END -- etc...
But I can't include this with the data retrieval operations. How would I go about doing this?

SELECT c.[UnitReference] AS 'UnitRef',
t.[NodeName] AS 'Property',
( CASE
WHEN d.MainImage IS NULL
THEN 'Main Image is Null, '
WHEN d.MainImage = ''
THEN 'Main Image is Empty, '
ELSE ''
END )+
( CASE
WHEN d.Summary IS NULL
THEN 'Summary is Null, '
WHEN d.Summary = ''
THEN 'Summary is Empty, '
ELSE ''
END )+
( CASE
WHEN d.[Description] IS NULL
THEN 'Description is Null, '
WHEN d.[Description] = ''
THEN 'Description is Empty, '
ELSE ''
END ) AS MissingFields
FROM [DetailPage] d
INNER JOIN [CRM] c
ON d.ItemID = c.ItemID
INNER JOIN [Tree] t
ON d.[ID] = t.[ID]
WHERE( d.MainImage IS NULL OR d.MainImage = '' )
OR ( d.Summary IS NULL OR d.Summary = '' )
OR ( d.[Description] IS NULL OR d.[Description] = '' )
AND c.[IsListed] = 1
AND c.[IsMarketed] = 1

Related

Filter result using alias

I have a query like this
SELECT
Type = TXL.Descript, Jurisdiction = CASE WHEN TX.State = 'KD' THEN 'FD'
WHEN TX.County > '' AND TX.County IS NOT NULL THEN 'Local' ELSE 'Country' END,
State = CASE WHEN TX.State = 'FD' OR (TX.County > '' AND TX.County IS NOT NULL) THEN '' ELSE (select top 1 istIntlStateDesc from IntStateM ISM where ISM.istIntlStateCode = TX.MtcState) END,
Local = CASE WHEN TX.County > '' AND TX.County IS NOT NULL THEN TX.MtcCounty ELSE '' END,
TaxCode = TX.TaxCode, TaxDescription = TX.TaxCodeDesc, EffectiveDate = ET.EtxEffectiveDate,
Taxable = ''
FROM
ETaX ET WITH (NOLOCK)
INNER JOIN TxCast TX on ET.Code = TX.TaxCode
INNER JOIN TxLMast TXL on TXL.TCode = TX.Tax
WHERE
ET.TDate <= GETDATE()
AND ET.SDate > GETDATE()
In the UI I have a table and I want to filer each column by passing the column name and what my code is doing is adding an AND condition to the WHERE clause while filtering but if I am passing the alias name (Ex. Jurisdiction) I am getting an error like - Invalid column name 'Jurisdiction', I also can't pass the actual column name as I am using case statement in the query, for example alias Jurisdiction value is coming by combing 2 column name so, is there any way it will work even passing the alias name or any better way to do it like dynamic SQL or any other workaround?
If I understand correctly, you want to filter by your "aliased" fields. To do so, you have 2 options:
Use subquery writing a SELECT FROM your entire query and then filtering by Jurisdiction:
SELECT * FROM
(SELECT
Type = TXL.Descript, Jurisdiction = CASE WHEN TX.State = 'KD' THEN 'FD'
WHEN TX.County > '' AND TX.County IS NOT NULL THEN 'Local' ELSE 'Country' END,
State = CASE WHEN TX.State = 'FD' OR (TX.County > '' AND TX.County IS NOT NULL) THEN '' ELSE (select top 1 istIntlStateDesc from IntStateM ISM where ISM.istIntlStateCode = TX.MtcState) END,
Local = CASE WHEN TX.County > '' AND TX.County IS NOT NULL THEN TX.MtcCounty ELSE '' END,
TaxCode = TX.TaxCode, TaxDescription = TX.TaxCodeDesc, EffectiveDate = ET.EtxEffectiveDate,
Taxable = ''
FROM
ETaX ET WITH (NOLOCK)
INNER JOIN TxCast TX on ET.Code = TX.TaxCode
INNER JOIN TxLMast TXL on TXL.TCode = TX.Tax
WHERE
ET.TDate <= GETDATE()
AND ET.SDate > GETDATE()) AS AUX_QUERY
WHERE
Jurisdiction = -your condition here-
(Note now Jurisdiction is a result field from AUX_QUERY)
Repeat the full CASE WHEN TX.State = 'KD' THEN 'FD' WHEN TX.County > '' AND TX.County IS NOT NULL THEN 'Local' ELSE 'Country' END that you called Jurisdiction in the WHERE clause (or wherever you want to use those calculated fields:
SELECT
Type = TXL.Descript, Jurisdiction = CASE WHEN TX.State = 'KD' THEN 'FD'
WHEN TX.County > '' AND TX.County IS NOT NULL THEN 'Local' ELSE 'Country' END,
State = CASE WHEN TX.State = 'FD' OR (TX.County > '' AND TX.County IS NOT NULL) THEN '' ELSE (select top 1 istIntlStateDesc from IntStateM ISM where ISM.istIntlStateCode = TX.MtcState) END,
Local = CASE WHEN TX.County > '' AND TX.County IS NOT NULL THEN TX.MtcCounty ELSE '' END,
TaxCode = TX.TaxCode, TaxDescription = TX.TaxCodeDesc, EffectiveDate = ET.EtxEffectiveDate,
Taxable = ''
FROM
ETaX ET WITH (NOLOCK)
INNER JOIN TxCast TX on ET.Code = TX.TaxCode
INNER JOIN TxLMast TXL on TXL.TCode = TX.Tax
WHERE
ET.TDate <= GETDATE()
AND ET.SDate > GETDATE()) AS AUX_QUERY
AND
CASE WHEN TX.State = 'KD' THEN 'FD'
WHEN TX.County > '' AND TX.County IS NOT NULL THEN 'Local' ELSE 'Country' END = -your condition here-
Aliases cannot be used like that, look at this example
declare #table1 table (id int, text1 varchar(50), text2 varchar(50))
insert into #table1 values (1, 'one', 'two')
select t1.id,
fullname = t1.text1 + ' ' + t1.text2
from #table1 t1
where fullname = 'one two'
This will throw this exception
Invalid column name 'fullname'
The most simple solution (imho) is this
select t.id,
t.fullname
from ( select t1.id,
fullname = t1.text1 + ' ' + t1.text2
from #table1 t1
) t
where t.fullname = 'one two'
This allows the database to fully evaluate the aliased columns, and therefore it will known them so you can use the aliased columns just like other columns

Two multi-value parameters in SSRS

I have two multi-value parameters in my SQL: where (PayToTIN IN (#PayToTIN) or PCP_ProvId IN (#PCP_ProvId). I am trying to drop in multiple values in either or parameters however when I drop in a value in either parameter, SSRS treats the other parameter as ''. I am also unable to null out the either param because they are multi-value. Is there a workaround to run multiple values in either one or the other parameter?
Declare #PayToTIN as varchar(max) = '562660402' --'562660402'
Declare #PCP_ProvId as varchar(max) --= 'LASRL12550' --'LASRL12550'
declare #detailfields as varchar(max) = NULL
declare #PayToTIN_switch varchar(max) =
( select max(PayToTIN)
from LA_Temp.dbo.vMemberPCP
where cast(PayToTIN as varchar) in (#PayToTIN)
)
declare #PCPAssignmentID_switch varchar(max) =
( select max(PCP_ProvId)
from LA_Temp.dbo.vMemberPCP
where cast(PCP_ProvId as varchar) in (#PCP_ProvId)
)
declare #include_PayToTIN bit = case when 'Pay To Tin' in (#detailfields) then 1 else 0 end
declare #include_PCP_ProvId bit = case when 'PCP ProvID' in (#detailfields) then 1 else 0 end
select distinct
x.CarrierMemID
-- , MemberName
, MbrLastName =rtrim( e.LastName)
, MbrFirstName = rtrim(e.FirstName)
, MbrMI = rtrim(e.MiddleName)
, x.DOB
, x.Age
, x.Sex
, Address = e.addr1
, City = e.city
, State = e.state
, Zip = e.zip
, Parish = e.county
, MemPhone = e.phone
, PCPName
, PCP_NPI
, PCPProvID
, PCPEffDate
, Specialty
, ServiceLocation
, PayToProvider
, PayToTIN
, PayToProvID
, PCP_ProvId
, PCPAssignment
from LA_Temp.dbo.vMemberPCP x
inner join PlanReport_QNXT_LA.dbo.enrollkeys ek
on x.enrollid = ek.enrollid
inner join PlanReport_QNXT_LA.dbo.orgpolicy o
on o.orgpolicyid = ek.orgpolicyid
and right(rtrim(o.policynum),2) <> 'BH'
inner join PlanReport_QNXT_LA.dbo.member m
on ek.memid = m.memid
inner join PlanReport_QNXT_LA.dbo.entity e
on e.entid = m.entityid
--where PayToTIN = #PayToTIN --AMB 05/07/18
where (PayToTIN IN (#PayToTIN)
or '' = #PayToTIN_switch
)
or ( PCP_ProvId IN (#PCP_ProvId)
or '' = #PCPAssignmentID_switch
)
where (case when PayToTIN = '' then null else PayToTIN end in (#PayToTIN))
OR (case when PCP_ProvId = '' then null else PCP_ProvId end in (#PCP_ProvId))

How to speed up a SQL query which is using DISTINCT

From what I have read about this it seems like the best solution is to create an INDEX but I am not sure which columns I should be creating indexes for. This is my first time working with SQL indexes.
If I remove the DISTINCT call from this query I get over 1000 results in just over a second. However with the DISTINCT call it returns the results in 10 seconds (obviously without the duplicates).
If anyone has any alternative solutions I am all ears.
This is the query (the second SELECT is where the DISTINCT function is called):
SELECT
Sku,
Name,
ccp.Polygon,
MarketAvailability,
Coverage,
Range
FROM
(SELECT DISTINCT
dbo.CatalogEntry.CatalogEntryId as Id,
dbo.CatalogEntry.Code as Sku,
CoverageNode.Name as Coverage,
RangeNode.Name as [Range],
(SELECT CatalogContentProperty.LongString
FROM CatalogContentProperty
WHERE MetaFieldName = 'ItemChartName'
AND (CatalogContentProperty.LongString IS NOT NULL)
AND (CatalogContentProperty.ObjectId = dbo.CatalogEntry.CatalogEntryId)) AS [Name],
(SELECT CatalogContentProperty.LongString
FROM CatalogContentProperty
WHERE MetaFieldName = 'MarketAvailabilityDetailsCollection'
AND (CatalogContentProperty.LongString IS NOT NULL)
AND (CatalogContentProperty.ObjectId = dbo.CatalogEntry.CatalogEntryId)) AS MarketAvailability
FROM
dbo.CatalogEntry
INNER JOIN
dbo.NodeEntryRelation ON dbo.CatalogEntry.CatalogEntryId = dbo.NodeEntryRelation.CatalogEntryId
INNER JOIN
dbo.CatalogNode AS CoverageNode ON dbo.NodeEntryRelation.CatalogNodeId = CoverageNode.CatalogNodeId
INNER JOIN
dbo.CatalogNode AS RangeNode ON CoverageNode.ParentNodeId = RangeNode.CatalogNodeId
INNER JOIN
dbo.CatalogContentProperty ON dbo.CatalogEntry.CatalogEntryId = dbo.CatalogContentProperty.ObjectId
INNER JOIN
dbo.CatalogNode AS ModelNode ON RangeNode.ParentNodeId = ModelNode.CatalogNodeId
INNER JOIN
dbo.CatalogNode AS BrandNode ON ModelNode.ParentNodeId = BrandNode.CatalogNodeId
WHERE
(dbo.CatalogEntry.ClassTypeId = N'Variation') AND
(dbo.CatalogContentProperty.MetaFieldName = N'ItemIsChart') AND
RangeNode.Name != 'C-MAP' AND
(BrandNode.Name = '' OR '' = '' OR '' IS NULL) AND
(ModelNode.Name = '' OR '' = '' OR '' IS NULL) AND
(CoverageNode.Name = '' OR '' = '' OR '' IS NULL) AND
(RangeNode.Name = '' OR '' = '' OR '' IS NULL)
) AS CmapResults
INNER JOIN
(SELECT
GEOMETRY::STGeomFromText(CatalogContentProperty.LongString,4326) AS PolygonGeometry,
CatalogContentProperty.LongString AS Polygon,
CatalogContentProperty.ObjectId
FROM
CatalogContentProperty
WHERE
MetaFieldName = 'ItemChartCoordinates' AND
(CatalogContentProperty.LongString IS NOT NULL)) ccp ON ccp.ObjectId = CmapResults.Id
WHERE
((GEOGRAPHY::STGeomFromText(PolygonGeometry.MakeValid().STUnion(PolygonGeometry.MakeValid().STStartPoint()).STAsText(), 4326).STDistance(GEOGRAPHY::STGeomFromText('POINT(50.9835929 -1.4205852)', 4326)) / 1609.344) <= 100 OR 'POINT(50.9835929 -1.4205852)' IS NULL)
AND MarketAvailability IS NOT NULL
ORDER BY
GEOGRAPHY::STGeomFromText(PolygonGeometry.MakeValid().STUnion(PolygonGeometry.MakeValid().STStartPoint()).STAsText(), 4326).STArea() DESC;
I am using SQL Server Management Studio 2012. The aim is to get the query with the DISTINCT call to return in the same amount of time as the query would without the DISTINCT call.
Your query looks a bit complicated. Will this one produce the same output?
SELECT DISTINCT ce.Code as Sku
, max(case when ccp.MetaFieldName = 'ItemChartName' then ccp.LongString end) as 'Name'
, max(case when ccp.MetaFieldName = 'MarketAvailabilityDetailsCollection' then ccp.LongString end) as 'MarketAvailability'
, max(case when ccp.MetaFieldName = 'ItemChartCoordinates' then ccp.LongString end) as 'Polygon'
, CoverageNode.Name as Coverage
, RangeNode.Name as 'Range'
FROM dbo.CatalogEntry ce
INNER JOIN dbo.NodeEntryRelation ner ON ce.CatalogEntryId = ner.CatalogEntryId
INNER JOIN dbo.CatalogNode CoverageNode ON dbo.NodeEntryRelation.CatalogNodeId = CoverageNode.CatalogNodeId
INNER JOIN dbo.CatalogNode RangeNode ON CoverageNode.ParentNodeId = RangeNode.CatalogNodeId
INNER JOIN dbo.CatalogContentProperty ccp ON ce.CatalogEntryId = ccp.ObjectId
INNER JOIN dbo.CatalogNode ModelNode ON RangeNode.ParentNodeId = ModelNode.CatalogNodeId
INNER JOIN dbo.CatalogNode BrandNode ON ModelNode.ParentNodeId = BrandNode.CatalogNodeId
WHERE ce.ClassTypeId = N'Variation'
and ccp.MetaFieldName = N'ItemIsChart'
and RangeNode.Name != 'C-MAP'
--and (BrandNode.Name = '' OR '' = '' OR '' IS NULL) -- always true
--and (ModelNode.Name = '' OR '' = '' OR '' IS NULL) -- always true
--and (CoverageNode.Name = '' OR '' = '' OR '' IS NULL) -- always true
--and (RangeNode.Name = '' OR '' = '' OR '' IS NULL) -- always true
and (GEOGRAPHY::STGeomFromText(GEOMETRY::STGeomFromText(ccp.LongString,4326).MakeValid().STUnion(GEOMETRY::STGeomFromText(ccp.LongString,4326).MakeValid().STStartPoint()).STAsText(), 4326).STDistance(GEOGRAPHY::STGeomFromText('POINT(50.9835929 -1.4205852)', 4326)) / 1609.344) <= 100 -- OR 'POINT(50.9835929 -1.4205852)' IS NULL -- redundant
)
and max(case when ccp.MetaFieldName = 'MarketAvailabilityDetailsCollection' then ccp.LongString end)
ORDER BY GEOGRAPHY::STGeomFromText(GEOMETRY::STGeomFromText(ccp.LongString,4326).MakeValid().STUnion(GEOMETRY::STGeomFromText(ccp.LongString,4326).MakeValid().STStartPoint()).STAsText(), 4326).STArea() DESC;
So the answer is my case was to remove the DISTINCT and to do the duplicate removing using LINQ! Load times went from 10-11ish seconds to 4-5ish seconds

Search filter on two fields based upon condition

Here is my table
create table Table1 (Id int, ...some fields... , CategoryId int, ProfileId int)
I want to write a SP(stored procedure) which will give me search results from the table based upon the parameters passed to the SP. Here is my procedure
Create proc Search
(
#MediaType1 varchar(1000),
#MediaType2 varchar(1000),
#MediaType3 varchar(1000)
)
as
begin
select * from table
where
case when #MediaType1 = '' then 1 else CategoryId end in
(select case when #MediaType1 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType1 when '0,' then '1,2,3,4' when '' then '1,' else #MediaType1 end,','))
and
case when #MediaType2 = '' then 1 else ProfileId end in
(select case when #MediaType2 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType2 when '0,' then '2,12,13' when '' then '1,' else #MediaType2 end,','))
and
case when #MediaType3 = '' then 1 else ProfileId end in
(select case when #MediaType3 = '' then 1 else Splvalue end
from dbo.Split(case #MediaType3 when '0,' then '1,14,15,16' when '' then '1,' else #MediaType3 end,','))
end
Basically, what I want to achieve is when '0' is passed in #MediaType1 variable, it should return all records which have category (1,2,3,4) else it should only that category which is passed (e.g. 3) else if its blank, it should show all records. Same way for #MediaType2 and #MediaType3 except that they should check for ProfileId. The condition is also that all three or two or one of the parameters could be blank, I need to handle those and show the filtered records.
My above query works only if one parameter is passed and rest all are blank. I also tried
where
(#MediaType1 <> '' and Category in (select Splvalue from dbo.Split(#MediaType1,',')))
or
(#MediaType2 <> '' and ProfileId in (select Splvalue from dbo.Split(#MediaType2 ,',')))
or
(#MediaType3 <> '' and ProfileId in (select Splvalue from dbo.Split(#MediaType3 ,',')))
but even this does not works. Any help would be appreciated
If I just rewrite what you said as conditions:
SELECT * FROM table
WHERE
(#MediaType1 = '' OR (#MediaType1 = 0 AND CategoryId IN (1,2,3,4))
OR #MediaType1 = CategoryId)
AND
(#MediaType2 = '' OR (#MediaType2 = 0 AND ProfileId IN (1,2,3,4))
OR #MediaType2 = ProfileId )
AND
(#MediaType3 = '' OR (#MediaType3 = 0 AND ProfileId IN (1,2,3,4))
OR #MediaType3 = ProfileId )
I just wrote the SP like this and it worked
Create proc Search
(
#MediaType1 varchar(1000),
#MediaType2 varchar(1000),
#MediaType3 varchar(1000)
)
as
begin
if (#MediaType1 = '' and #MediaType2 = '' and #MediaType3 = '')
begin
set #MediaType1 = '0,';
set #MediaType2 = '0,';
set #MediaType3 = '0,';
end
select * from table
where
((#MediaType1 = '0,' and CategoryId in (1,2,3,4)) or (CategoryId in (select Splvalue from dbo.Split(#MediaType1,','))))
or
((#MediaType2 = '0,' and ProfileId in (2,12,13)) or (ProfileId in (select Splvalue from dbo.Split(#MediaType2 ,','))))
or
((#MediaType3 = '0,' and ProfileId in (1,14,15,16)) or (ProfileId in (select Splvalue from dbo.Split(#MediaType3 ,','))))
end

CASE still returns null

Trying to get the output in Dx_3 to print '' if it is NULL but everything I have tried (NULLIF(), COALESCE(), ELSE '', etc) still prints a NULL.
SELECT
#RecordType AS RecordType_1
,AbstractData.AccountNumber AS AcctNum_2
,(SELECT
CASE
WHEN AD.Diagnosis IS NOT NULL THEN AD.Diagnosis
ELSE ''
END
FROM AbsDrgDiagnoses AD
WHERE (AD.DiagnosisSeqID ='1' AND AD.VisitID = AbstractData.VisitID)) AS Dx_3
FROM AbstractData --214
WHERE AbstractData.PtStatus <> 'REF'
SELECT #RecordType AS RecordType_1,
AbstractData.AccountNumber AS AcctNum_2,
COALESCE(AD.Diagnosis, '') AS Dx_3
FROM AbstractData
LEFT JOIN AbsDrgDiagnoses AD ON AD.VisitID = AbstractData.VisitID
WHERE AbstractData.PtStatus <> 'REF' AND AD.DiagnosisSeqID = '1'