I want to obtain from a parameter, #Display the value 0, 1 or 2. When #Display = 0, I want to display all the items for which ec.IsEquipmentRelated is true. When #Display = 0, I want to display all the items for which ec.IsEquipmentRelated is false and when #Display = 2, I want to display all the items for which ec.IsEquipmentRelated is true OR false. How can I implement this in the FROM section?
ALTER PROCEDURE [dbo].[Downtime_GetNewCause_EquimentLocation]
#DisplayInactive bit = 0,
#SortOrder INT = 0,
#Diplay INT = 0
AS
-- Main Data source
SELECT ic.IncidentCauseID
, 'EquimentRelated' = COALESCE(ec.IsEquipmentRelated, 0)
, ic.NewIncidentCauseID
, ic.DisplayName
, ic.IsLegacy
, el.EquipmentLocationID
, el.ShopID
, ec.EquipmentClassID
, ec.EquipmentAbbr
, el.ClassSequenceNumber
, el.EquipmentComponent
, el.CompSequenceNumber
, ic.IsActive
FROM Downtime_IncidentCauses ic
LEFT JOIN Downtime_EquipmentLocations el ON ic.EquipmentLocationID = el.EquipmentLocationID
LEFT JOIN Downtime_EquipmentClasses ec ON el.EquipmentClassID = ec.EquipmentClassID AND
CASE WHEN #Diplay = 0 THEN ...
CASE WHEN #Diplay = 1 THEN ...
CASE WHEN #Diplay = 2 THEN ...
This should work:
INNER JOIN Downtime_EquipmentClasses ec
ON (el.EquipmentClassID = ec.EquipmentClassID)
AND ( (#Display = 0 AND ec.IsEquipmentRelated = 1)
OR (#Display = 1 AND ec.IsEquipmentRelated = 0)
OR (#Display = 2) )
Do it in a WHERE clause:
WHERE (#Display = 0 AND ec.IsEquipmentRelated = 'True')
OR (#Display = 1 AND ec.IsEquipmentRelated = 'False')
OR #Display = 2
Related
I have two tables in oracle DB called collection and collection_h. I have to delete all the records from collection_h which has the same below fields in the collection table.
I have to delete all the records from collection_h table that comes out as a result of the below query:
select * from collection inner join collection_h on
collection.pos_protocol_id = collection_h.pos_protocol_id and
collection.terminal_pos_number = collection_h.terminal_pos_number and
collection.cb_file_number = collection_h.cb_file_number and
collection.cb_block_number = collection_h.cb_block_number and
collection.is_stan_batch = collection_h.is_stan_batch and
collection.is_transaction_date = collection_h.is_transaction_date and
collection.is_stan_trans = collection_h.is_stan_trans;
Delete where exists
delete
from collection as c
where exists (
select 1
from collection_h as h
where h.pos_protocol_id = c.pos_protocol_id
and h.terminal_pos_number = c.terminal_pos_number
and h.cb_file_number = c.cb_file_number
and h.cb_block_number = c.cb_block_number
and h.is_stan_batch = c.is_stan_batch
and h.is_transaction_date = c.is_transaction_date
and h.is_stan_trans = c.is_stan_trans
);
Simplified test on db<>fiddle here
But if the columns can have NULL's in the matching rows
delete
from collection as c
where exists (
select 1
from collection_h as h
where decode(h.pos_protocol_id, c.pos_protocol_id, 0, 1) = 0
and decode(h.terminal_pos_number, c.terminal_pos_number, 0, 1) = 0
and decode(h.cb_file_number, c.cb_file_number, 0, 1) = 0
and decode(h.cb_block_number, c.cb_block_number, 0, 1) = 0
and decode(h.is_stan_batch, c.is_stan_batch, 0, 1) = 0
and decode(h.is_transaction_date, c.is_transaction_date, 0, 1) = 0
and decode(h.is_stan_trans, c.is_stan_trans, 0, 1) = 0
);
Delete x from collection X inner join collection_h Y on
X.pos_protocol_id = Y.pos_protocol_id and
X.terminal_pos_number = Y.terminal_pos_number and
X.cb_file_number = Y.cb_file_number and
X.cb_block_number = Y.cb_block_number and
X.is_stan_batch = Y.is_stan_batch and
X.is_transaction_date = Y.is_transaction_date and
X.is_stan_trans = Y.is_stan_trans;
I eventually managed to get what I was after by grouping and then applying an additional filter with 'HAVING' which is probably not the best way to go about it, but I am new to SQL and this is the only way I could achieve what I was after... which was a list of 'simple' items where the 'qty' is 0 and the range status (attribute_id = 168) is Discontinued (ID 96) and the 'status' (attribute_id = 97) is enabled (id = 1). This is shown below:
SELECT
`mgic_catalog_product_entity`.`sku` AS `sku`,
`mgic_catalog_product_entity`.`type_id` AS `type_id`,
`mgic_cataloginventory_stock_item`.`qty` AS `qty`,
MAX(Case WHEN `mgic_eav_attribute`.`attribute_id` = 97 THEN `mgic_catalog_product_entity_int`.`value` END) AS status,
MAX(Case WHEN `mgic_eav_attribute`.`attribute_id` = 168 THEN `mgic_catalog_product_entity_int`.`value` END) AS range_status
FROM (((`mgic_eav_attribute`
join `mgic_catalog_product_entity_int` on ((`mgic_eav_attribute`.`attribute_id` = `mgic_catalog_product_entity_int`.`attribute_id`)))
join `mgic_catalog_product_entity` on ((`mgic_catalog_product_entity_int`.`entity_id` = `mgic_catalog_product_entity`.`entity_id`)))
join `mgic_cataloginventory_stock_item` on ((`mgic_catalog_product_entity_int`.`entity_id` = `mgic_cataloginventory_stock_item`.`product_id`)))
WHERE `mgic_catalog_product_entity`.`type_id` = 'simple' AND `mgic_cataloginventory_stock_item`.`qty` = 0
GROUP BY `mgic_catalog_product_entity`.`sku`
HAVING status = 1 and range_status = 96;
I am now trying to amend this to an update instruction to set the 'status' (attribute_id = 97) to disabled (id = 2) for the results list of the below query.
update mgic_eav_attribute ea join
mgic_catalog_product_entity_int cpei on ea.attribute_id = cpei.attribute_id join
mgic_catalog_product_entity cpe on cpei.entity_id = cpe.entity_id join
mgic_cataloginventory_stock_item cisi on cpei.entity_id = cisi.product_id
set cpei.value = 2
WHERE cpe.type_id = 'simple' AND ((ea.attribute_code = 'status') and
(cpei.value = 1)) AND cisi.qty = 0 AND EXISTS(
SELECT
cpe.sku,
cpe.type_id,
cisi.qty,
MAX(Case WHEN ea.attribute_id = 97 THEN cpei.value END) AS status,
MAX(Case WHEN ea.attribute_id = 168 THEN cpei.value END) AS range_status
FROM (((`mgic_eav_attribute`
join `mgic_catalog_product_entity_int` on ((`mgic_eav_attribute`.`attribute_id` = `mgic_catalog_product_entity_int`.`attribute_id`)))
join `mgic_catalog_product_entity` on ((`mgic_catalog_product_entity_int`.`entity_id` = `mgic_catalog_product_entity`.`entity_id`)))
join `mgic_cataloginventory_stock_item` on ((`mgic_catalog_product_entity_int`.`entity_id` = `mgic_cataloginventory_stock_item`.`product_id`)))
WHERE `mgic_catalog_product_entity`.`type_id` = 'simple' AND `mgic_cataloginventory_stock_item`.`qty` = 0
GROUP BY cpei.entity_id
HAVING status = 1 and range_status = 96);
The above query just seems to hang and doesn't execute. Can anyone help?
I have a validation in WHERE clause like:
...
AND (#BDOnly = 0
OR [DT].[Abbreviation] = #IsBDChecked)
AND (#CDOnly = 0
OR [DT].[Abbreviation] = #IsCDChecked)
AND (#PPOOnly = 0
OR [DT].[Abbreviation] = #IsPPOChecked)
AND (#FBOMOnly = 0
OR [DT].[Abbreviation] = #IsFBOMChecked)
AND (#APOnly = 0
OR [DT].[Abbreviation] = #IsAPChecked)
AND (#COOnly = 0
OR [DT].[Abbreviation] = #IsCOChecked)
So each AND clause check if boolean is bit value is 0 or 1, if it's 0 just do any but if it's 1 it do a filter. My problem is
if I'm sending two with value 1, I mean
#BDOnly = 1 and #CDOnly = 1 it only filter one of them instead get two filters I mean:
[DT].[Abbreviation] = #IsBDChecked
and
[DT].[Abbreviation] = #IsCDChecked
What am I doing wrong? Regards
I'm going to take a guess here because there's not enough data. If you want to return a row where Abbreviation matched #IsBDChecked only when #BDOnly is set, and also another row where Abbreviation matches #IsCDChecked when #CDOnly is set, try this:
(#BDOnly = 1
AND [DT].[Abbreviation] = #IsBDChecked)
OR (#CDOnly = 1
AND [DT].[Abbreviation] = #IsCDChecked)
OR (#PPOOnly = 1
AND [DT].[Abbreviation] = #IsPPOChecked)
OR (#FBOMOnly = 1
AND [DT].[Abbreviation] = #IsFBOMChecked)
OR (#APOnly = 1
AND [DT].[Abbreviation] = #IsAPChecked)
OR (#COOnly = 1
AND [DT].[Abbreviation] = #IsCOChecked)
Small representative case:
DECLARE #ADOnly BIT = 0
, #BDOnly BIT = 1
, #CDOnly BIT = 1
, #IsADChecked NVARCHAR(100) = 'A'
, #IsCDChecked NVARCHAR(100) = 'C'
, #IsBDChecked NVARCHAR(100) = 'B'
;WITH myTable AS
(
SELECT * FROM (VALUES ('A'), ('B'), ('C')) X(Abbreviation)
)
SELECT *
FROM myTable
WHERE (#ADOnly = 1 AND Abbreviation = #IsADChecked)
OR (#BDOnly = 1 AND Abbreviation = #IsBDChecked)
OR (#CDOnly = 1 AND Abbreviation = #IsCDChecked)
Yields:
Abbreviation
------------
B
C
I have this query
SELECT DISTINCT IP.IRId
FROM cmp.NPTable NP
INNER JOIN IPTable IP ON IP.IPtId = NP.IPd
LEFT JOIN IPCTable IPC ON IPC.IPId = NP.IPId
WHERE NP.PCN Id = #PCNId
AND (IP.IsCompliant = 1 AND IPC.CheckId = 1) OR (IP.IsCompliant = 0 AND IPC.CheckId = 1)
This is not working correcty
THe IPTable either has IsCompliant = null, 0 or 1 -- this is basically to indicate true or false
IPC.CheckId is either 1 or 2 -- this is the primary ID in this table
The only match integer match is the value 1 between the two tables.
I only want to bring back rows if IsCompliant = 1 and CheckId = 1
else if IsCompliant is null or 0, then CheckId = 2.
The clause I added to my where which is
AND (IP.IsCompliant = 1 AND IPC.CheckId = 1) OR (IP.IsCompliant = 0 AND IPC.CheckId = 1)
This does not work. Help. Will be very appreciated.
Thanks
WHERE NP.PCN Id = #PCNId
AND
(
(IP.IsCompliant = 1 AND IPC.CheckId = 1) OR
((IP.IsCompliant is null or IP.IsCompliant = 0) AND IPC.CheckId = 2)
)
I am making an rdl report and I have three check-boxes that if checked need to alter my WHERE statement. If none are checked the result should only match by date range. If one or more are checked it needs to return the fields that match the variables corresponding string.
WHERE
(EffectiveDate BETWEEN #StartDate AND #EndDate)
AND (((#IncludeSEWPrefix = 1 AND PrefixId = 'SEW') OR #IncludeSEWPrefix = 0)
AND ((#IncludePAWPrefix = 1 AND PrefixId = 'PAW') OR #IncludePAWPrefix = 0)
AND ((#IncludeRPLPrefix = 1 AND PrefixId = 'RPL') OR #IncludeRPLPrefix = 0))
My code so far works when none are checked and when one is checked, but returns nothing when more than one check-box has been checked. So to try and fix this I altered the code to this
WHERE
(EffectiveDate BETWEEN #StartDate AND #EndDate)
AND ((((#IncludeSEWPrefix = 1 AND PrefixId = 'SEW') OR #IncludeSEWPrefix = 0)
OR ((#IncludePAWPrefix = 1 AND PrefixId = 'PAW') OR #IncludePAWPrefix = 0)
OR ((#IncludeRPLPrefix = 1 AND PrefixId = 'RPL') OR #IncludeRPLPrefix = 0)))
Which resulted in all rows being returned no matter what was selected. Can someone tell me where I am going wrong?
I believe this is the correct rearrangement. Trickier problem than it first appears. The issue was seperating lines like ((#IncludeSEWPrefix = 1 AND PrefixId = 'SEW') OR #IncludeSEWPrefix = 0) with AND meant that if two includes were true, a row would need to have both PrefixId's, which can't happen. And if you separated them with OR, then having just one include false, means that every row will pass. So instead, check that a row has the prefix of any that are included, otherwise all includes have to be off.
WHERE EffectiveDate BETWEEN #StartDate AND #EndDate
AND
(
(#IncludeSEWPrefix = 1 AND PrefixId = 'SEW') OR
(#IncludePAWPrefix = 1 AND PrefixId = 'PAW') OR
(#IncludeRPLPrefix = 1 AND PrefixId = 'RPL') OR
(#IncludeSEWPrefix = 0 AND #IncludePAWPrefix = 0 AND #IncludeRPLPrefix = 0)
)
Try this
WHERE
(EffectiveDate BETWEEN #StartDate AND #EndDate)
AND
(
(#IncludeSEWPrefix = 1 AND PrefixId = 'SEW' OR #IncludeSEWPrefix = 0) AND
(#IncludePAWPrefix = 1 AND PrefixId = 'PAW' OR #IncludePAWPrefix = 0) AND
(#IncludeRPLPrefix = 1 AND PrefixId = 'RPL' OR #IncludeRPLPrefix = 0)
)
You have more parenthesis than needed, it does not hurt but just be aware.
Maybe this can help:
WHERE (EffectiveDate BETWEEN #StartDate AND #EndDate)
AND ( ((#IncludeSEWPrefix = 1 AND PrefixId = 'SEW') OR (#IncludeSEWPrefix = 0 AND #PrefixId <> 'SEW'))
OR ((#IncludePAWPrefix = 1 AND PrefixId = 'PAW') OR (#IncludePAWPrefix = 0 AND #PrefixId <> 'PAW'))
OR ((#IncludeRPLPrefix = 1 AND PrefixId = 'RPL') OR (#IncludeRPLPrefix = 0 AND #PrefixId <> 'RPL'))
)