Single Query To Select Based On Parameters If Or not supplied - sql

I have used SqlDataSource and have a select query based on District & Zone as below
SELECT a.[committee_id] memberid, a.[membername], a.[memberemail], a.[memberdesignation], a.[membercreatedby],b.districtname AS district,b.districtid,c.zone_name AS zone,c.zoneid
FROM [committee_details] a
LEFT JOIN district_master b on b.districtid=a.districtid
LEFT JOIN zone_master c on c.districtid=a.districtid and c.zoneid = a.zoneid
WHERE (a.[membercreatedby] = 'director') AND ((convert(varchar,a.districtid) LIKE '%2%') AND (convert(varchar,a.zoneid) LIKE '%25%')) ORDER BY a.[committee_id] DESC
It's an inline query. I have tried above query but not able to figure out how to Select condition based.
I want if district supplied then Select according to District, if both District & Zone supplied then Select according to both & If nothing supplied then Select All. But should be in single query. How should I do this?

First, fix your query so you are not using meaningless table aliases. Use table abbreviations! I would also drop all the square braces; they just make the query harder to write and to read.
Basically, you want comparisons with NULL in the WHERE clause. I have no idea why your sample code uses LIKE, particularly columns that appear to be numbers. Nothing in the question explains why LIKE is used for the comparison, so the idea is:
SELECT cd.committee_id as memberid, cd.membername,
cd.memberemail, cd.memberdesignation, cd.membercreatedby,
dm.districtname AS district, dm.districtid,
zm.zone_name AS zone, zm.zoneid
FROM committee_details cd LEFT JOIN
district_master dm
ON cd.districtid = dm.districtid LEFT JOIN
zone_master zm
ON zm.districtid = cd.districtid AND
zm.zoneid = cd.zoneid
WHERE cd.membercreatedby = 'director') AND
(cd.districtid = #district or #district is null) AND
(cd.zoneid = #zone or #zone is null)
ORDER BY cd.[committee_id] DESC;
If you were using LIKE, then I would phrase the logic like:
WHERE cd.membercreatedby = 'director') AND
(cast(cd.districtid as varchar(255)) like #district) AND
(cast(cd.zoneid as varchar(255)) like #zone)
And pass in the patterns as '%' when you want all values to match. This assumes that the columns in cd are not NULL. If they can be NULL, then you want an explicit comparison, as in the first example.

If I got the question right then you can use parameters and compare to the column itself if the values are not supplied or not present.
try the following:
SELECT a.[committee_id] memberid, a.[membername], a.[memberemail], a.[memberdesignation], a.[membercreatedby],b.districtname AS district,b.districtid,c.zone_name AS zone,c.zoneid
FROM [committee_details] a
LEFT JOIN district_master b on b.districtid=a.districtid
LEFT JOIN zone_master c on c.districtid=a.districtid and c.zoneid = a.zoneid
WHERE (a.[membercreatedby] = 'director')
AND b.districtname = isnull(nullif(#districtname, ''), b.districtname)
AND c.zone_name = isnull(nullif(#zone_name, ''), c.zone_name)
ORDER BY a.[committee_id] DESC

Related

IF NULL select data from another table

I am trying to get the HTS "harmonized code" from two different tables.
STKMP purchased, STKMM Manufactured.
When I run my query, there are items that are missing the HTS from STKMP, I would like to replace NULLS
with the data on STKMM. I have tried case when but it gives me no results.
Select distinct
ltrim(rtrim(boldh.FEBOL#)) as BOL,
--ltrim(rtrim(bolh.FESCS#)) as ShipTo,
--ltrim(rtrim(bolh.FESNME)) as CustomerName,
--ltrim(rtrim(bolh.FGCPO#)) as CustPO,
--ltrim(rtrim(ocri.DDCSPI)) as CustLine,
ltrim(rtrim(bold.FGCPT#)) as CustPart,
ltrim(rtrim(bolh.FESNME)) as CustName,
ltrim(rtrim(bolh.FESAD1)) as CustStreet,
ltrim(rtrim(bolh.FESAD2)) as CustStreet1,
ltrim(rtrim(bolh.FESAD3)) as CustCityState,
ltrim(rtrim(stkmp.AWHARM)) as HTS,
case when STKMP.AWHARM is null then STKMM.AVHARM else stkmp.AWHARM end as HTTT,
ltrim(rtrim(V6CORG)) as COO,
ltrim(rtrim(awdes1)) as Descrip
--ltrim(rtrim([FGQSHO])) as QTY
FROM BOLH
left join bold on bolh.FEBOL# = bold.FGBOL#
left join ocri on bold.FGORD# = ocri.DDORD# and bold.FGITEM = ocri.DDITM#
left join STKA on ocri.DDPART = stka.v6part
left join STKMP on stka.V6PART = STKMP.AWPART
left join STKMM on STKMP.AWPART = STKMM.AVPART
Thanks
COALESCE ( expression [ ,...n ] )
Reference: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/coalesce-transact-sql?view=sql-server-ver15
COALESCE(STKMP.AWHARM, stkmp.AWHARM) AS HTTT
Alternatively, to see if you got some issues with your joins and/or both values are null you could take it one step further, like this.
COALESCE(STKMP.AWHARM, stkmp.AWHARM, 'Both values are NULL') AS HTTT
Also, there are few more other options are there.
By using ISNULL
SELECT ISNULL(STKMP.AWHARM, stkmp.AWHARM) AS HTTT
By Using IIF Statement
SELECT IIF(STKMP.AWHARM IS NOT NULL,STKMP.AWHARM,stkmp.AWHARM) AS HTTT

how to add a conditional statement after calculating two fields in SQL

I need to output data based on a condition to limit output to usable data. Need help with understanding and optimizing query and removing redundancies for my SQL query
I tried conditions in the where statement, but that is giving me an error. Also tried adding a Having statement, which did not work either.
select
o2.car_move_id as Carrier_Code,
o1.early_shpdte,
o1.prtnum,
shpsts,
(o1.host_ordqty / o3.untqty) as Order_pallets,
(
select
count(i3.untqty)
from
INVENTORY_PCKWRK_VIEW i3
inner join prtftp_dtl i4 on i3.prtnum = i4.prtnum
where
i3.invsts like 'U'
and i3.wrkref is null
and i3.prtnum = o1.prtnum
and i3.untqty = i4.untqty
and i4.uomcod like 'PL'
and i4.wh_id like 'RX'
) as full_pallets,
(
select
count(i5.untqty)
from
INVENTORY_PCKWRK_VIEW i5
inner join prtftp_dtl i6 on i5.prtnum = i6.prtnum
where
i5.invsts like 'U'
and i5.wrkref is null
and i5.prtnum = o1.prtnum
and i5.untqty < i6.untqty
and i5.prtnum = i6.prtnum
and i6.uomcod like 'PL'
and i6.wh_id like 'RX'
) as Partial_pallets
from
ord_line o1
inner join SHIP_STRUCT_VIEW o2 on o1.ordnum = o2.ship_id
inner join prtftp_dtl o3 on o1.prtnum = o3.prtnum
where
o2.ship_id like '0%'
and shpsts in ('R', 'I')
and o1.non_alc_flg = 0
and o3.wh_id like 'RX'
and o3.uomcod like 'PL'
order by
full_pallets asc,
o1.early_shpdte asc
I want to only output the query where order_pallets > Full_Pallets. not sure where I can add this condition in my query.
The items on the SELECT list of an SQL query are logically processed after the WHERE clause (as explained in this answer), that's why you cannot reference column aliases in the WHERE clause. You will need to use a subselect to accomplish what you want:
select * from (
select
o2.car_move_id as Carrier_Code,
o1.early_shpdte,
o1.prtnum,
shpsts,
-- the rest of your current query
) t
where t.order_pallets > t.Full_Pallets
You can enclose your entire query in
with x as ()
Then select from it:
select * from x
where x.order_pallets > x.full_pallets
This will save you from having to maintain multiple subqueries for the same information.

Select row from a MAX() GROUP BY in SQL Server

I have a table I called Eventos. I have to select the corresponding outTime from the alarm which has the greater inTime.
And I have to do it quickly/optimized. I have about 1 million entries in the table.
This is my code:
SELECT
CadGrupoEventos.Severidade AS Nível,
CadGrupoEquipamentos.Nome AS Grupo,
CadEquipamentos.TAG AS Equipamento,
CadEventos.MensagemPT AS 'Mensagem de alarme',
MAX(Eventos.InTime) AS 'Hora do evento',
Eventos.OutTime AS 'Hora de saída'
FROM
CadGrupoEventos,
CadEquipamentos,
CadEventos,
Eventos,
CadUsuarios,
CadGrupoEquipamentos
WHERE
Eventos.Acked = 0
AND CadGrupoEventos.Codigo = CadEventos.Grupo
AND CadEquipamentos.Codigo = Eventos.TAG
AND CadEventos.Codigo = Eventos.CodMensagem
AND CadGrupoEquipamentos.Codigo = CadEquipamentos.Grupo
GROUP BY
CadGrupoEventos.Severidade,
CadEquipamentos.TAG,
CadEventos.MensagemPT,
CadGrupoEquipamentos.Nome,
Eventos.OutTime
This code, as it is, returns every single entry from the table.
I have to take Eventos.OutTime out of GROUP BY and still get the value of it.
This is just an educated guess based on your description. Notice I used ANSI-92 style joins which are much more explicit. I also used aliases to make this a lot more legible. Your query might look something like this.
select x.Severidade AS Nível,
x.Nome AS Grupo,
x.TAG AS Equipamento,
x.MensagemPT AS [Mensagem de alarme],
x.[Hora do evento],
x.OutTime AS [Hora de saída]
from
(
SELECT cge.Severidade,
cgequip.Nome,
ce.TAG,
cevt.MensagemPT,
MAX(e.InTime) AS [Hora do evento],
e.OutTime
, RowNum = ROW_NUMBER() over(partition by cge.Severidade, ce.TAG, cevt.MensagemPT, cgequip.Nome order by e.OutTime /*maybe desc???*/)
FROM CadGrupoEventos cge
join CadEventos cevt on cge.Codigo = cevt.Grupo
join Eventos e on AND cevt.Codigo = e.CodMensagem
join CadEquipamentos ce on ce.Codigo = e.TAG
join CadGrupoEquipamentos cgequip on cgequip.Codigo = ce.Grupo
cross join CadUsuarios cu --not sure if this is really what you want but your original code did not have any logic for this table
WHERE e.Acked = 0
GROUP BY cge.Severidade,
ce.TAG,
cevt.MensagemPT,
cgequip.Nome,
e.OutTime
) x
where x.RowNum = 1

Comparing Query Result With Table and Retrieve Specific Field

My Query
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
Again I would like to compare the query result columns
sStockistCode
sStateName
sDivision
with tblStockistMaster with the same fields
sStockistCode
sStateName
sDivision
and retrieve the STOCKIST NAME.
Don't know how to compare the above query result with the table.
Maybe you can use following SQL code used with CTE expression
;with cte as (
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
)
select
cte.*,
sm.sStockistName
from cte
left join tblStockistMaster as sm
on sm.sStockistCode = cte.sStockistCode and
sm.sStateName = cte.sStateName and
sm.sDivision = cte.sDivision
-- I retrieve the stockist Name
SELECT
stoMast.sStockistName,
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast
ON stateMap.sStateName = stoMast.sStateName
-- I'm joining table entry If I can match
LEFT JOIN
tblEntry tbl
on tbl.sStockistCode = stoMast.sStockistName
AND tbl.sStateName = stoMast.sStateName
AND tbl.sDivision = stoMast.sDivision
AND tbl.sRMCode = stateMap.sRMCode
WHERE
stateMap.sRMCode = 'MCNE04001'
and stoMast.sDivision = 'CIDIS'
-- And The the exept thing, I don't want that got a match with the tableentry
AND COALESCE(tbl.sStockistCode, tbl.sStateName, tbl.sDivision, tbl.sRMCode) is null
I expect it is what you wanted to get. On another way please help us understand wht you come from (tables and idea of what data can be in) and the result you want. Will be easier to create a query.

Is it possible to insert an IF clause inside of a WHERE clause in a SELECT?

sorry if this is a dumb question, I'm new to PL/SQL.
I have a PL/SQL Stored Procedure which retrieves data from a table.
There are 2 optional parameters which can be null. If they're not null they should be part of the WHERE clause.
This is the SELECT:
SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION
FROM MAS_PART PN
LEFT JOIN CF_DESCRIPTION DES
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID
WHERE PN.PART_CODE = 'M'
AND PN.PART_TYPE_ID = IN_PART_TYPE_ID
AND PN.PART_GROUP_ID = IN_PART_GROUP_ID
ORDER BY PN.PART_NUMBER;
The two variables are IN_PART_TYPE_ID and IN_PART_GROUP_ID. Is there any way to evaluate the WHERE clauses regarding these two variables only when they're NOT NULL? Or the only way is to repeat the SELECT 3 times using IF clauses and changing the WHERE clauses?
OR operatior will help:
SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION
FROM MAS_PART PN
LEFT JOIN CF_DESCRIPTION DES
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID
WHERE PN.PART_CODE = 'M'
AND (PN.PART_TYPE_ID = IN_PART_TYPE_ID or IN_PART_TYPE_ID is null)
AND (PN.PART_GROUP_ID = IN_PART_GROUP_ID or IN_PART_GROUP_ID is null)
ORDER BY PN.PART_NUMBER;
Another option is to use NVL:
SELECT DISTINCT PN.PART_NUMBER, PN.SHORT_CODE, DES.DESCRIPTION
FROM MAS_PART PN
LEFT JOIN CF_DESCRIPTION DES
ON PN.LOCAL_DESCRIPTION_ID = DES.DESCRIPTION_ID
WHERE PN.PART_CODE = 'M'
AND PN.PART_TYPE_ID = NVL(IN_PART_TYPE_ID, PN.PART_TYPE_ID)
AND PN.PART_GROUP_ID = NVL(IN_PART_GROUP_ID, PN.PART_GROUP_ID)
ORDER BY PN.PART_NUMBER;
But it will work only if PN.PART_TYPE_ID and PN.PART_GROUP_ID is not null