SQL Conditional statement with 2 variables showing unexpected results - sql

I have a SP that i need to filter based on:
....
where
and cs.chargetype = #chargetype
AND (#chargetype = 'Q' and
(#biweeklypart = 1 and datepart(dd,cs.scheduledate) = 15)
OR
(#biweeklypart = 1 and datepart(dd,cs.scheduledate) <> 15)
)
But is not working.
What I need is that only when #chargetype = 'Q' and #biweeklypart = 1 then I have to filter by datepart(dd,cs.scheduledate) = 15, and if #chargetype = 'Q' and #biweeklypart = 2 then I have to filter by datepart(dd,cs.scheduledate) <> 15.
Any clue? I thought I was doing right.

Based on your description, you want this:
where cs.chargetype = #chargetype and
( (#chargetype = 'Q' and #biweeklypart = 1 and day(cs.scheduledate) = 15) or
(#chargetype = 'Q' and #biweeklypart = 2 and day(cs.scheduledate) <> 15) or
(#chargetype <> 'Q')
)

Related

How to update this Select Query to Update? - So far, it just hangs

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?

Filter only get one condition

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

Datatables combine data from different columns into single row

Refer to the below image, how to merge all chapter into one single rows of different page number?
e.g.
Page 1 has 3 rows as there are 3 data at columns of chp 8,9,10
Page 2 has 5 rows as there are 5 data at columns of chp 8,9,1,11,12
So
how to have a single row of each page number and the all data placed at their own chp?
Basic SQL as below:
SELECT `mc_ee_page_id` as Page,
IF ( mc_ee_chp_id = 1, ( CASE
WHEN (is_marked = 0 and mk_no_mark = 1 ) THEN "Y"
WHEN (is_marked = 1 and mk_no_mark = -1) THEN "N"
WHEN (is_marked = 1 and mk_no_mark = 1 ) THEN "O" ELSE "X"
END ) , "" ) AS chp_1 ,
IF ( mc_ee_chp_id = 2, ( CASE
WHEN (is_marked = 0 and mk_no_mark = 1 ) THEN "Y"
WHEN (is_marked = 1 and mk_no_mark = -1) THEN "N"
WHEN (is_marked = 1 and mk_no_mark = 1 ) THEN "O" ELSE "X"
END ) , "" ) AS chp_2 ,
IF ( mc_ee_chp_id = 3, ( CASE
WHEN (is_marked = 0 and mk_no_mark = 1 ) THEN "Y"
WHEN (is_marked = 1 and mk_no_mark = -1) THEN "N"
WHEN (is_marked = 1 and mk_no_mark = 1 ) THEN "O" ELSE "X"
END ) , "" ) AS chp_3 ,
:
:
IF ( mc_ee_chp_id = 12, ( CASE
WHEN (is_marked = 0 and mk_no_mark = 1 ) THEN "Y"
WHEN (is_marked = 1 and mk_no_mark = -1) THEN "N"
WHEN (is_marked = 1 and mk_no_mark = 1 ) THEN "O" ELSE "X"
END ) , "" ) AS chp_12
FROM `maxcare_mc_ee_hw`
WHERE `stud_id` = '3312' AND `mc_ee_level_id` = '1'
GROUP BY mc_ee_chp_id, mc_ee_page_id
ORDER BY mc_ee_page_id asc
LIMIT 500
One way would be to GROUP the results of your SQL by making it the subquery of an outer query...
SELECT Page, MAX(chp_1) AS chp_1, MAX(chp_2) AS chp_2, MAX(chp_3) AS chp_3, MAX(chp_4) AS chp_4, MAX(chp_5) AS chp_5, MAX(chp_6) AS chp_6, MAX(chp_7) AS chp_7, MAX(chp_8) AS chp_8, MAX(chp_9) AS chp_9, MAX(chp_10) AS chp_10, MAX(chp_11) AS chp_11, MAX(chp_12) AS chp_12
FROM
(
-- *** paste your SQL in here ***
) AS indivdual_rows
GROUP BY Page
It assumes a page cannot have more than one non-blank value for the same chapter. If that is not the case, then it will only show the MAX alphabetical value.
Click here to go to SQL Fiddle to see it in action.

SQL - WHERE with CASE statement

SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE
(CASE
WHEN DATALENGTH(CostRule.ModelName) = 0
THEN
CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1
ELSE
CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1
END
)
) AS MonoCost
I want to define my where statement depending on the datalength of CostRule.ModelName. But i got an error: Incorrect syntax near '='. in CostRule.Type = 1 and i got a error in the ELSE statement.
Must be like this:
...
WHERE
(DATALENGTH(CostRule.ModelName) = 0
AND CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1)
OR
(DATALENGTH(CostRule.ModelName) != 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1)
The CASE-style from your query cannot work.
you can change your statement like this:
SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE CostRule.ColorType=1
AND CostRule.Type=CASE WHEN DATALENGTH(CostRule.ModelName) = 0 THEN 1 ELSE 2 END
AND CostRule.Manufacturer=CASE WHEN DATALENGTH(CostRule.ModelName) = 0 THEN Printer.ManufacturerId ELSE Printer.ModelName END
You can't use a CASE statement to define where conditions like that. It will be easier to just use some boolean logic
SELECT *
FROM your_table
WHERE (DATALENGTH(CostRule.ModelName) = 0
AND CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1)
OR (DATALENGTH(CostRule.ModelName) != 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1)
There are some other things that could be removed (like CostRule.ColorType = 1 since it is the same in both branches) but I've left them in here to illustrate how to transform your CASE statement into a boolean logic set.
It looks like you would just need to change the WHERE statement:
It looks like you will just need to change your WHERE statement to use OR and remove the CASE Statement.
(SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE
DATALENGTH(CostRule.ModelName) = 0
CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1
OR
DATALENGTH(CostRule.ModelName) <> 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1
) AS MonoCost

SELECT FROM depending on a parameter in SQL

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