Where condition is not working - mysql

I have a SQL query. But that contains a where condition, and the OR in that where is not working.
Query
SELECT `st_student`.`st_id`, `ab_date`, `as_date` `st_status`
FROM (`st_student`)
WHERE `st_status` = 1
OR `st_status` = 2
AND `ab_date` BETWEEN '08/01/2015' AND '08/31/2015'
OR `as_date` BETWEEN '08/01/2015' AND '08/31/2015'
AND `aca_no` = 2
GROUP BY `st_student`.`st_id`
This condition is not working:
OR `as_date` BETWEEN '08/01/2015' AND '08/31/2015'
Is there any mistake in that?

One possible error concerns the use of the AND and OR operators, since AND has priority over OR, and your query can be interpreted in the wrong way. So you should use the parentheses, and write something like this:
SELECT `st_student`.`st_id`, `ab_date`, `as_date` `st_status`
FROM `st_student`
WHERE (`st_status` = 1 OR `st_status` = 2)
AND (`ab_date` BETWEEN '08/01/2015' AND '08/31/2015'
OR `as_date` BETWEEN '08/01/2015' AND '08/31/2015')
AND `aca_no` = 2
GROUP BY `st_student`.`st_id`

In case that your columns are declared as a varchar datatype you will need to use str_to_date function. Varchar cannot be compared as a date unless you convert it to one. Try this and let me know. Best of luck.
SELECT `st_student`.`st_id`, `ab_date`, `as_date` `st_status`
FROM `st_student`
WHERE (`st_status` = 1 OR `st_status` = 2)
AND STR_TO_DATE(`ab_date`,'%d/%m/%Y')
BETWEEN
STR_TO_DATE('01/08/2015','%d/%m/%Y')
AND
STR_TO_DATE('31/08/2015','%d/%m/%Y')
OR
STR_TO_DATE(`as_date`,'%d/%m/%Y')
BETWEEN
STR_TO_DATE('01/08/2015','%d/%m/%Y')
AND
STR_TO_DATE('31/08/2015','%d/%m/%Y')
AND `aca_no` = 2
GROUP BY `st_student`.`st_id`

Related

Is there a way to make an AND operation over a column of TINYINT(1) in MYSQL?

I got the following table and I need to return 1 if all rows have disponibilidad = 1
The following QUERY works just fine, but i was looking for a more efficient way of doing it.
QUERY:
SELECT IF(AVG(disponibilidad) < 1, 0, 1) AS newResult
FROM pasteleria.compone
RIGHT JOIN pasteleria.ingredientes
ON pasteleria.compone.id_ingrediente = pasteleria.ingredientes.id_ingrediente
WHERE id_componente = 1;
RESULT:
As I see it, with an 'AND' it would be far more efficient, since it wouldn't have to do AVG().
MySql does not support a boolean AND aggregate function like Postgresql's bool_and.
Why not a simple MIN():
SELECT MIN(disponibilidad) AS newResult
FROM pasteleria.compone
RIGHT JOIN pasteleria.ingredientes
ON pasteleria.compone.id_ingrediente = pasteleria.ingredientes.id_ingrediente
WHERE id_componente = 1;
This will return 1 only if all values of the column are 1 (provided the column is not nullable) and 0 if there is at least one row with 0.
How about something like
SELECT IF(COUNT(*)>0,0,1) AS newResult
FROM pasteleria.compone
RIGHT JOIN pasteleria.ingredientes
ON pasteleria.compone.id_ingrediente = pasteleria.ingredientes.id_ingrediente
WHERE id_componente = 1
AND disponibilidad <> 1
so that if there are any rows where disponibilidad is not 1, you output 0, otherwise if it's zero (so all disponibilidad values are 1) you output 1?

What's wrong with this SQL query WHERE AND clause?

Previously, this was working:
$patient_story_set_photos = $wpdb->get_results('SELECT * FROM wp_before_after WHERE patientID = '.$post->ID.' AND patient_display = 1');
However, when I try to add another AND condition like this:
$patient_story_set_photos = $wpdb->get_results('SELECT * FROM wp_before_after WHERE patientID = '.$post->ID.' AND patient_display = 1 AND period_taken = '.$set->period_taken);
I get the following error on screen:
WordPress database error: [Unknown column '1hour' in 'where clause']
SELECT * FROM wp_before_after WHERE patientID = 8175 AND patient_display = 1 AND period_taken = 1hour
Can't see why there's a problem, are you not allowed to use multiple AND conditions in SQL?
The problem is not the AND, the problem is your 1hour, 1hour unquoted means a reference to an object (database, table) named 1hour, you need to quote '1hour'.
If you write
SELECT * FROM wp_before_after
WHERE patientID = 8175
AND patient_display = 1
AND period_taken = '1hour'
you will compare the field periodtaken to a string (CHAR,VARCHAR,TEXT) equal to '1hour'.
I assume period_taken is a field typed CHAR,VARCHAR or TEXT
Before anything, DO NOT CONCATENATE SQL STRINGS nowadays it is a MUST (see how to do it properly https://stackoverflow.com/a/60496/3771219)
The problem you are facing is because, I presume, that the period_taken field is some sort of Char/Varchar/String field and when you are filtering by a "Stringy" field you must sorround your literals values with single quotes:
SELECT *
FROM wp_before_after
WHERE patientID = 8175
AND patient_display = 1
AND period_taken = '1hour'
Hope this help

Updating column values as per our format

There are two types of records in my Db such as MS-NW and CS in the same column of table DICIPLINE I want to wrap if its CS (ANY TWO STRING LIKE CS,TE OR THE LIKE) then wrap it to BS(CS) (OR BS(TE) ETC) or if its MS-NW (Or MS-CS, MS-TE and the like) then wrap it to MS(NW) from the column dicipline.
I updated for two strings successfully and following is the query for that kindly let me know how can i do it for values like MS-NW OR MS-CS and convert it to the format like MS(NW) from following query .
UPDATE DEG set DICIPLINE = concat("BS(",DICIPLINE,")") where CHAR_LENGTH(DICIPLINE) = 2
The below query helps you to update your data.
update deg set DISIPLINE = if(length(DISIPLINE)= 2,concat('BC(',DISIPLINE,')')
,concat('MS(',substr(DISIPLINE, 4,4),')'));
See Sqlfiddle demo.
For safety, create a temporary column of same type and perform an update like this:
UPDATE deg
SET dicipline_temp = CASE
WHEN CHAR_LENGTH(dicipline) = 2
THEN CONCAT('BS(', dicipline, ')')
WHEN CHAR_LENGTH(dicipline) = 5 AND SUBSTRING(dicipline, 3, 1) = '-'
THEN CONCAT(REPLACE(dicipline, '-', '('), ')')
END
WHERE CHAR_LENGTH(dicipline) = 2 OR (CHAR_LENGTH(dicipline) = 5 AND SUBSTRING(dicipline, 3, 1) = '-')
If results are acceptable, update the actual column.

In SQL, is there something like: WHERE x = ANY_VALUE?

In a SQL query like this:
SELECT *
FROM MyTable
WHERE x = 5;
is it possible to modify the WHERE condition so that SELECT looks for every value of x? Something like (wrong syntax):
SELECT *
FROM MyTable
WHERE x = ANY_VALUE;
The reason behind this question is that I have to parse and modify some SQL queries through some C++ code I am writing. I know in this case I could just remove or comment the whole WHERE condition, but this is a simplification.
Thank you.
In cases like this, you normally would do something like this:
SELECT *
FROM MyTable
WHERE x = SOME_VALUE OR 1 = 1;
SOME_VALUE is arbitrary, it can be anything matching the type of the column, because the WHERE clause will always be true because of the second part.
You could just omit WHERE clause. :)
While I think it's really the wrong way to go about it (just make the effort to remove the Where), how about where x = x? It won't work if X is null (you'd have to use "x is null or x = x") but don't bother if you know x won't be null.
You can try that:
SELECT *
FROM MyTable
WHERE x = x OR x IS NULL;
You could make your query like this
DECLARE #VALUE as (type of x)
--SET #VALUE = ''
SELECT *
FROM MyTable
WHERE (#VALUE IS NULL OR x = #VALUE);
and your parse would only have to replace
the: --SET #VALUE = '' line for one with the value you want, minus the comment, like: SET #VALUE = 'abc'
hope this helps

IF condition in mysql

I have a contact table I wish to query when a certain condition exists. I tried the query below but am getting a syntax error.
SELECT *
FROM contact_details
WHERE contactDeleted` =0
AND IF ( contactVisibility = "private"
, SELECT * FROM contact_details
WHERE contactUserId = 1
, IF( contactVisibility = "group"
, SELECT * FROM contact_details
WHERE contactGroup = 3
)
)
If I'm understanding your question correctly (which is difficult with the lack of info you've provided. Sample datasets and expected outcomes are typically helpful), then I don't believe you need IFs at all for what you want. The following will return contacts that are not deleted and who either have (visibility = "private" and userId = 1) OR (visibility = "group" and group = 3)
SELECT *
FROM contact_details
WHERE contactDeleted = 0
AND (
(contactVisibility = "public")
OR
(contactVisibility = "private" AND contactUserId = 1)
OR
(contactVisibility = "group" AND contactGroup = 3)
)
I am assuming you want to use the IF() function and not the statement which is for stored functions..
Refer to this link for more information on that.
Notice that you have put 2 select statements in there, where the custom return values are supposed to be. So you are returning a SELECT *... now notice that in your upper level sql statement you have an AND.. so you basically writing AND SELECT *.. which will give you the syntax error.
Try using .. AND x IN (SELECT *) .. to find if x is in the returned values.
Let me also list this link to make use of an existing and well written answer which may also applicable to your question.