Mysql syntax error on IF statement [closed] - mysql

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I try get vacancies per course, cause have limited vacancies per course;
So a need return:
Course 1 - No vacancies
Course 2 - 2 vacancies
SELECT
curs.CURSO_ID,
curs.CURSO_NOME,
curs.CURSO_DATA_INICIO,
curs.CURSO_DATA_FIM,
curs.CURSO_DESCRICAO,
curs.CURSO_LINK,
cate.CAT_CUR_ID,
cate.CAT_CUR_DESCRICAO,
curs.CURSO_VAGAS,
(
SELECT COUNT(sol.SOLI_ID)
FROM
solicitacao AS sol
WHERE
sol.SOLI_FK_CURSO_ID = curs.CURSO_ID
) AS pedido,
IF (
curs.CURSO_VAGAS > pedido THEN (curs.CURSO_VAGAS - pedido) ELSE 0
) AS totalVagas
/** CASE WHEN (curs.CURSO_VAGAS > pedido) THEN (curs.CURSO_VAGAS - pedido) ELSE 0 END AS totalVagas **/
FROM
curso AS curs
LEFT JOIN curso_categoria AS cate ON cate.CAT_CUR_ID = curs.CURSO_FK_CATEGORIA_ID
ORDER BY
CURSO_DATA_INICIO ASC
Thanks for help

Try this IF syntax:
IF (curs.CURSO_VAGAS > (
SELECT COUNT(sol.SOLI_ID)
FROM solicitacao AS sol
WHERE
sol.SOLI_FK_CURSO_ID = curs.CURSO_ID
), (curs.CURSO_VAGAS - (
SELECT COUNT(sol.SOLI_ID)
FROM solicitacao AS sol
WHERE
sol.SOLI_FK_CURSO_ID = curs.CURSO_ID
)), 0) AS totalVagas
You can use alias name only in GROUP BY, ORDER BY, or HAVING clauses

Try another solution:
IF (curs.CURSO_VAGAS > (SELECT pedido), (curs.CURSO_VAGAS - (SELECT pedido )), 0) AS totalVagas

Related

expected that this query will not output 0 values, but it does [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
Improve this question
I expected that this query will not output 0 values, but it does. I thought that and (...) > 0 will not output 0 values. So how I can prevent the output of 0 values?
select lot.*, sum(movement.quantity) as value
from lot
left join lot_movement as movement on lot.id = movement.lot_id
where lot.item_id = 8 and movement.storage_id = 3
and (select sum(lot_movement.quantity)
from lot_movement
where lot_movement.lot_id = lot.id
) > 0
group by lot.id;
I tried to add and sum(lot_movement.quantity) \> 0, but this gives error invalid use of group function.
lots in database
lot_movements in database
output with 0 values
I see that
and (select sum(lot_movement.quantity)
from lot_movement
where lot_movement.lot_id = lot.id
group by lot_movement.lot_id) > 0
is redundant. It doesn't affect the result.
Your query doesn't give the expected result because you're filtering by lot.item_id = 8 and movement.storage_id = 3 in the where clause, but you're not applying that same filtering in the subselect.
I'm not exactly sure what you're trying to achieve, but I suspect adding a having clause instead of the subselect solves your problem:
select lot.id, sum(movement.quantity) as value
from lot
left join lot_movement as movement on lot.id = movement.lot_id
where lot.item_id = 8 and movement.storage_id = 3
group by lot.id
having sum(movement.quantity) > 0

mySQL: Select first number not in subquery results [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a column itemId that contains unique IDs in the format US001, US002, US003 etc.
The trailing numbers of these IDs are not consecutive as rows may have been deleted.
I am looking for a way to find the first number that DOES NOT EXIST in my column.
Example 1:
Column: US001, US002, US004, US006.
Expected result: 3.
Example 2:
Column: US001, US002, US003, US004, US007.
Expected result: 5.
Example 3:
Column: US001, US002, US003, US004, US005.
Expected result: 6.
I tried the following but this returns NULL or no results (also no error):
SELECT MIN((RIGHT(i.itemId, 3)) + 1) AS nextAvailableId
FROM items i
WHERE RIGHT(i.itemId, 3) NOT IN
(
SELECT * FROM
(
SELECT RIGHT(i2.itemId, 3) AS itemNo
FROM items i2
) AS x
)
Can anyone please help me with this ?
Thanks,
Tim
Here is one option using window functions and string functions:
select min(id) + 1 as nextAvailableId
from (
select substr(itemid, 2) as id,
lead(substr(itemid, 2)) over(order by substr(itemid, 2)) as lead_id
from mytable t
) t
where lead_id > id + 1 or lead_id is null
In MySQL 5.x, where string functions are not available, you can use a subquery:
select min(substr(itemid, 2)) + 1 as nextAvailableId
from mytable
where not exists (
select 1
from mytable t1
where substr(t1.itemid, 2) = substr(t.itemid, 2) + 1
)

Query for students passed or not passed in specific Subjects [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have a Table with Column Headings:
ID Student_Name
Roll_Number
Subject1MarksObtained
Subject1TotalMarks
Subject2MarksObtained
Subject2TotalMarks
Subject3MarksObtained
Subject3TotalMarks
Subject4MarksObtained
Subject4TotalMarks
I want to write a query to output the results for individual student who have pass at least three of the subjects.
Without seeing the data, lets make some assumptions:
A pass is awarded for a subject if the marks obtained for that subject are equal to or more than 50% of the total marks available for that subject.
The name of the table is called Enrollment
To return a list of students who have passed at least 3 subjects we can use a query similar to the following:
This solution uses CASE to evaluate a 1 for a pass and a 0 for fail for each subject, then we sum those results and only return rows that have a score of 3 or more.
SELECT ID, Student_Name, Roll_Number
FROM Enrollment
WHERE
( CASE WHEN (Subject1MarksObtained / Subject1TotalMarks) >= 0.5 THEN 1 ELSE 0 END
+ CASE WHEN (Subject2MarksObtained / Subject2TotalMarks) >= 0.5 THEN 1 ELSE 0 END
+ CASE WHEN (Subject3MarksObtained / Subject3TotalMarks) >= 0.5 THEN 1 ELSE 0 END
+ CASE WHEN (Subject4MarksObtained / Subject4TotalMarks) >= 0.5 THEN 1 ELSE 0 END
) >= 3
There are different way to approach this, but this query is simple to read and gets the job done.
If you are querying an access table, then CASE WHEN is not supported but you can use IIF or SWITCH to achieve the same results:
SELECT ID, Student_Name, Roll_Number
FROM Enrollment
WHERE
( IIF( (Subject1MarksObtained / Subject1TotalMarks) >= 0.5, 1, 0)
+ IIF( (Subject2MarksObtained / Subject2TotalMarks) >= 0.5, 1, 0)
+ IIF( (Subject3MarksObtained / Subject3TotalMarks) >= 0.5, 1, 0)
+ IIF( (Subject4MarksObtained / Subject4TotalMarks) >= 0.5, 1, 0)
) >= 3
Let's instead start by fixing your broken schema. A normalised design might look somewhat as follows:
Student
ID
Student_Name
Roll_Number
Results
StudentID
Subject
Mark

Mysql where clause column IN query not giving correct results [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Table:
From the above table, below query is not giving proper result.
SELECT * FROM `support_profile`
WHERE `packageName` LIKE 'Platinum' AND `columnValue` IN ('50','150');
Result:
I need a query for checking the data is changed or not for the perticular packageName and columnValue?
Here is the internal representation of IN
Where `columnValue` In (50) => Where (columnValue = 50)
Where `columnValue` In (50,100) => Where ( (columnValue = 50) OR (columnValue =100) )
Your query:
SELECT * FROM `support_profile`
WHERE `packageName` LIKE 'Platinum' AND `columnValue` IN ('50','150');
is equivalent to
SELECT * FROM `support_profile`
WHERE
(
(`packageName` LIKE 'Platinum')
AND
(
(`columnValue` = '50')
OR (`columnValue` = '100')
)
);
Which will return all Platinum with columnValue 50 or 100.
if you wish to return only platinum 50 or platinum 100, you can group them. (make sure which of the latest record you want by sorting the records)
SELECT * FROM `support_profile`
WHERE `packageName` LIKE 'Platinum' AND `columnValue` IN ('50','150')
GROUP BY `packageName`, `columnValue` ;
if you wish to know whether the package values have changed
SELECT * FROM `support_profile`, Count(distinct `columnValue`) as valueChanges
WHERE `packageName` LIKE 'Platinum' AND `columnValue` IN ('50','150')
GROUP BY `packageName` ;
you get
silver 2
gold 1
platinum 1
PS: Please do us a favor and search how to ask question here
If you want to get records which are IN (50,150) and don't want to compare package name then remove the like condition. Use query as below. I hope this help you to get exact output, and please post your expected output:
SELECT * FROM `support_profile` WHERE `columnValue` IN ('50','150');
If You want to check the data which are not match with 50 and 150 then you can try below query:
SELECT * FROM `support_profile` WHERE `packageName` LIKE 'Platinum' AND `columnValue` NOT IN ('50','150');
To check if both the data exist in table or not, use AND in WHERE as below:
SELECT * FROM `support_profile` WHERE `packageName` LIKE 'Platinum' AND `columnValue` = '50' AND `columnValue` = '150' ;

Using multiple OR in SQL [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to write a query which should check if there is at least one column which has a value greater than 0 (>0) in the table. Currently, I have written a 'WHERE' clause with multiple OR conditions. I suspect that this may not be the best way of doing this (may be use SUM?). Seeking opinion from SQL experts.
WHERE raw_0 >0 OR raw_1 >0 OR raw_2 >0 OR raw_3 >0 OR raw_4>0
You can use
WHERE (raw_0 >0 OR raw_1 >0 OR raw_2 >0 OR raw_3 >0 OR raw_4>0);
As per your question. As dnoeth commented, is the easiest to write and understand (and probably the best for the optimizer as there's no calculation involved)
Alternatively you can use:
WHERE ((RAW_0 + RAW_1 + RAW_2 + RAW_3) > 0);
The above condition would be satisfied IF and only IF, atleast one of the values is >0.
You can also use concat operator to concat the strings and check if the concatenated string has value other than zero:
WHERE TO_NUMBER ( RAW_0 || RAW_1 || RAW_2 || RAW_3 ) > 0
Test data for 3rd query:
select 'YES value' data from dual where TO_NUMBER ( 1 || 2) > 0 ;
select 'NO value' data from dual where TO_NUMBER ( 0 || 0) > 0 ;
If the values can only be non-negative, as in one of the OP comment then you can check the multiplication
WHERE raw_0 * raw_1 * raw_2 * raw_3 * raw_4 > 0
but that will check if every value as positive. To check if only one is positive we can negate this logic using the SIGN function
WHERE (1 - SIGN(raw_0))
* (1 - SIGN(raw_1))
* (1 - SIGN(raw_2))
* (1 - SIGN(raw_3))
* (1 - SIGN(raw_4)) = 0
(1 - SIGN(value)) return 1 when the value is zero and 0 when the value is positive, so if at least one value is positive the product will be 0.