Select query on SQL where parameter1 OR parameter2 - sql

CREATE PROCEDURE [dbo].[SPPeople]
(
#Name varchar(50) = null,
#Status1 char(1) = '0',
#Status2 char(1) = '0',
#Status3 char(1) = '0'
)
as
SELECT
People.Name, People.Age
FROM
People
WHERE
(People.Name = CASE WHEN #Name is null THEN People.Name ELSE #Name END)
AND
((People.Status1 = CASE WHEN #Status1 = '0' THEN People.Status1 ELSE #Status1 END)
OR
(People.Status2 = CASE WHEN #Status2 = '0' THEN People.Status2 ELSE #Status2 END)
OR
(People.Status3 = CASE WHEN #Status3 = '0' THEN People.Status3 ELSE #Status3 END))
If parameters #Status1 and #Status2 are equal to 1, the query should return registers that necessarily have Status1 OR Status2 equal to 1, not depending on Status3.
But the query above returns all registers when I pass #Status1 and #Status2 as 1.

Try using this logic instead:
SELECT p.Name, p.Age
FROM People p
WHERE (#Name is null OR p.Name = #Name) AND
(#status1 <> '0' and p.Status1 = #status1 or
#status2 <> '0' and p.Status2 = #status2 or
#status3 <> '0' and p.Status3 = #status3
);
Most people find it more difficult to understand case expressions in the where clause than boolean logic.

I think you can modify your WHERE condition to compare against the parameter directly like
WHERE
People.Name = #Name
AND
(
People.Status1 = #Status1
OR
People.Status2 = #Status2
OR
People.Status3 = #Status3
)

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

SQL Server condition not working

Below is part of a SQL Server query which is not working as expected. I don't know why, but condition falls through this part, like nothing is inserted (like all three conditions are set to NULL). What am I doing wrong here?
Input parameters for the stored procedure:
#cStockPacked varchar(1) = NULL,
#cWrittenDown varchar(1) = NULL,
#cInPreparation varchar(1) = NULL
Part of the query which is not working:
(
(#cStockPacked IS NULL OR
(#cStockPacked = '1' AND MEST.MEST_STA = '1')
)
OR
(#cInPreparation IS NULL OR
(#cInPreparation = '1' AND MEST.MEST_STA = '2')
)
OR
(#cWrittenDown IS NULL OR
(#cWrittenDown = '1' AND MEST.MEST_STA = '4')
)
)
I've tried to hard code conditions, everything worked as expected:
(
MEST.MEST_STA = '1' OR MEST.MEST_STA = '2' OR MEST.MEST_STA = '4'
)
I've tried with one condition (hardcoded), then with two and later with all three. All was good. I want to achieve the same result with query pasted above, but something is obviously wrong. What am I doing wrong?
Whole procedure:
ALTER PROCEDURE [dbo].[sp_CAMERC_HLP]
( , #cStockPacked varchar(1) = NULL
, #cWrittenDown varchar(1) = NULL
, #cInPreparation varchar(1) = NULL
)
AS
BEGIN
SELECT
MEST.MEST_QUA, MERC_STA, MERC_NME,
MERC_DES, MERC_NTO, MERC_UNI, MERC_LPR,
MERC.UNIT_KEY,
COUNT_ALL_ROWS = COUNT(*) OVER()
FROM
CAMERC MERC
INNER JOIN
CAMEGR CAMEGR ON MERC.MEGR_KEY = CAMEGR.MEGR_KEY
INNER JOIN
CAMEST MEST ON MERC.MERC_KEY = MEST.MERC_KEY
WHERE
(#cMERC_NME IS NULL OR MERC_NME LIKE '%' + #cMERC_NME + '%')
AND
(#iMEGR_KEY IS NULL OR MERC.MEGR_KEY IN (SELECT MEGR_KEY FROM CTE))
AND
(#cMERC_CDO1 IS NULL OR MERC_CDO1 LIKE '%' + #cMERC_CDO1 + '%')
AND
and
(
(#cStockPacked IS NULL OR #cStockPacked = '1' AND MEST.MEST_STA = '1')
OR
(#cInPreparation IS NULL OR (#cInPreparation = '1' AND MEST.MEST_STA = '2'))
OR
(#cWrittenDown IS NULL OR (#cWrittenDown = '1' AND MEST.MEST_STA = '4'))
)
END
You may looking for this
(
(
(#cStockPacked IS NOT NULL AND #cStockPacked = '1' AND MEST.MEST_STA = '1') OR
(#cInPreparation IS NOT NULL AND #cInPreparation = '1' AND MEST.MEST_STA = '2') OR
(#cWrittenDown IS NOT NULL AND #cWrittenDown = '1' AND MEST.MEST_STA = '4')
)
OR
( #cStockPacked IS NULL OR #cInPreparation IS NULL OR #cWrittenDown IS NULL )
)
I don't understand why you accepted that answer as correct, it does not make much sense to test var for NULL with those conditions.
All you need - to make these conditions same as others. Just like this:
AND (#cMERC_NME IS NULL OR MERC_NME LIKE '%' + #cMERC_NME + '%')
update them to:
AND (#cStockPacked IS NULL OR (#cStockPacked = '1' AND MEST.MEST_STA = '1'))
AND (#cInPreparation IS NULL OR (#cInPreparation = '1' AND MEST.MEST_STA = '2'))
AND (#cWrittenDown IS NULL OR (#cWrittenDown = '1' AND MEST.MEST_STA = '4'))
that's it.

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

Concatenating multiple CASE statements into one alias

After some previous help on how to approach a problem I am having with some legacy code, it seems like the best approach for my issue is to concatenate case statements to return a value I can parse out in PHP.
I am trying to do something like this, but it is returning many rows, and eventually getting this error:
Maximum stored procedure, function, trigger, or view nesting level
exceeded (limit 32).
SELECT org.org_id,
org.org_name_1,
Datename(YEAR, member.enroll_date) AS enroll_year,
Max(CASE
WHEN board.member_from IS NULL THEN 0
ELSE 1
END) AS board_member,
CASE
WHEN ( org.delete_reason = 'OUT'
AND org.org_delete_flag = 'Y'
AND org.org_status_flag = 'C' ) THEN 'out_of_business|'
ELSE ''
END + CASE
WHEN ( stat.carrier = 'BS'
AND stat.status_id IS NOT NULL
AND stat.termination_date IS NULL
AND stat.flat_dues > 0 ) THEN 'insurance_member|'
ELSE ''
END + CASE
WHEN ( stat.carrier = 'BS'
AND stat.status_id IS NOT NULL
AND stat.termination_date IS NULL
AND stat.flat_dues = 0
AND member.status_flag IN( 'C', 'P' ) ) THEN 'insurance_product|'
ELSE ''
END + CASE
WHEN ( member.enroll_date IS NOT NULL
AND member.status_flag NOT IN( 'C', 'P' ) ) THEN 'member_since|'
ELSE ''
END + CASE
WHEN ( org.org_relationship_parent = 'Y'
AND org.dues_category = 'MBR'
AND org.org_status_flag = 'R' ) THEN 'subsidiary_member|'
ELSE ''
END + CASE
WHEN ( org.org_misc_data_9 = 'PAC' ) THEN 'pac|'
ELSE ''
END + CASE
WHEN ( org.dues_category = 'PART' ) THEN 'partner_member|'
ELSE ''
END + CASE
WHEN ( org.dues_category = 'FREE'
AND org.org_status_flag = 'P' ) THEN 'associate_member|'
ELSE ''
END
--ELSE 'non_member'
--END
AS org_status,
60 AS expires_in,
CASE
WHEN stat.dues_type = 'M' THEN
CASE
WHEN ( stat.termination_date IS NULL ) THEN ( stat.flat_dues )
ELSE 0
END
ELSE
CASE
WHEN ( member.payments = 0 ) THEN member.dues_billed_annual
ELSE member.payments
END
END AS dues_level,
CASE
WHEN ( org.affiliate_code = 'PCCE'
AND org.dues_category = 'MBR'
AND org.org_status_flag = 'R' ) THEN 1
ELSE 0
END AS pcce_membr,
-- '$'+CONVERT(VARCHAR,#dues) AS dues_level,
Ltrim(#product_level) AS product_level,
Ltrim(#involve_level) AS involvement_level
FROM organiz AS org
LEFT JOIN affilbil AS member
ON member.status_id = org.org_id
AND member.dues_category = 'MBR'
LEFT JOIN individu AS ind
ON ind.org_id = org.org_id
LEFT JOIN commembr AS board
ON board.status_id = ind.ind_id
AND board.committee_code = '5'
AND board.member_to IS NULL
LEFT JOIN statinsmorn AS stat
ON stat.status_id = org.org_id
AND stat.carrier = 'BS'
AND stat.planz = 'PCI'
WHERE org.org_id = #org_id
GROUP BY org.org_id,
org.org_name_1,
member.enroll_date,
org.delete_reason,
org.org_status_flag,
org.org_delete_flag,
stat.status_id,
stat.flat_dues,
stat.dues_type,
stat.termination_date,
org.org_misc_data_9,
org_relationship_parent,
org.dues_category,
member.status_flag,
member.dues_billed_annual,
member.payments,
stat.carrier,
org.Affiliate_Code
Well, this is embarrassing.
When I was making my changes to the stored procedure, I had inadvertently placed a call to the same procedure at the bottom. So I was recursively calling the same procedure over and over again. DOH.

FireBird: How do you nest a select in an if?

I'm very new to FireBird, but I want to know how I can use a select statement as part of my conditional criteria. I feel like I've been to the internet in back trying to find a way to do this, but haven't come up with much. Below is my attempt at getting this to work. Thanks in advance for any help.
SET TERM ^ ;
ALTER PROCEDURE sp_test (
IPADD Varchar(32),
HN Varchar(32),
NOTE Varchar(200) )
RETURNS ( update_count integer )
AS
BEGIN
IF((SELECT COUNT(*)
FROM ADDRESSES a
WHERE a.ADDRESS_TYPE = 'Reserved'
AND a.ALIVE = 'N'
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)) > 0)
THEN
UPDATE
ADDRESSES a
SET
a.HOST_NAME = :HN,
a.ADDRESS_TYPE = 'Assigned',
a.NOTES = :NOTE
WHERE
a.SHORT_IP_ADDRESS = :IPADD;
update_count = 1;
SUSPEND;
ELSE
update_count = 0;
SUSPEND;
END^
SET TERM ; ^
GRANT EXECUTE
ON PROCEDURE sp_test TO SYSDBA;
Using COUNT to check is there records to update is not the best way, use EXISTS instead, ie your IF would be
IF(EXISTS(SELECT 1 FROM ADDRESSES a
WHERE a.ADDRESS_TYPE = 'Reserved'
AND a.ALIVE = 'N'
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)))
THEN
But there seems to be a problem with your return value, update_count - you return 1 if you execute the UPDATE, but the actual number of rows affected by the statement might be something else. I suggest you use ROW_COUNT context variable instead. So your procedure would be
ALTER PROCEDURE sp_test (
IPADD Varchar(32),
HN Varchar(32),
NOTE Varchar(200) )
RETURNS ( update_count integer )
AS
BEGIN
IF(EXISTS(SELECT 1 FROM ADDRESSES a
WHERE (a.ADDRESS_TYPE = 'Reserved')
AND (a.ALIVE = 'N')
AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)))
THEN BEGIN
UPDATE ADDRESSES a SET
a.HOST_NAME = :HN,
a.ADDRESS_TYPE = 'Assigned',
a.NOTES = :NOTE
WHERE a.SHORT_IP_ADDRESS = :IPADD;
update_count = ROW_COUNT;
END ELSE update_count = 0;
SUSPEND;
END^