What is not valid about this MySQL syntax for CASE WHEN? - php

I'm trying to use the CASE WHEN statement, but it doesn't seem to work. Is there any change that I can make to this in order to make it work, or is it completely wrong?
"CASE
WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') WHERE id = :id
THEN UPDATE table SET f = 0 WHERE f = 1
WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') WHERE id = :id
THEN UPDATE table SET f = 1 WHERE id = :id
ELSE f
END"
I really can't figure this out, and I have tried looking for an answer in different places, but I can't find something similar. Thanks.
Edit:
This is not part of a SELECT statement. I have six columns and one unique id for each row. What I want, is that each row only have one of its columns set to 1, at a time. If a row has already one column set to 1, then you can't set another of its columns to 1. Also, if one column is already set to one in one row, then the same column can't be set to 1 in another row. So I guess that I want it to be mutually exclusive, both vertically and horizontally, hence why both WHEN statements are the same, the first one so that all previous rows that had a 1 in that column will be reseted to 0, before assigning the 1 to the specific chosen column (by id). I placed a WHERE inside the CASE statement because I thought you could do that, judging by the comments, I guess not.
That's the full query, I am using prepared statements, and before that, I had this:
$q = $con->query("UPDATE table SET f=0 WHERE f=1");
$q = $con->prepare("UPDATE table SET f=1 WHERE id = :id");
$q->execute(array('id' => "$id"));
I'm really a beginner with MySQL, so maybe my solution is laughable, and I'm sorry for that. I hope I could explain clearly what I want to do. I don't know where to find the error log, but after posting this, I'm looking for it, and will add a further update. So far I can tell you that I don't know if there's an error (but I'm pretty sure there is, judging by the replies), but what I can tell you is that upon executing the query, it does nothing.
Edit2:
Here's the error that I get when using the query that I posted:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE WHEN ...'
I'm trying other solutions...
Edit3:
Hello, I've managed to find a way to do what I was trying to do. I couldn't do it using only the CASE THEN syntax, and in fact I had to write a whole lot of new code (and queries), so I'm guessing that what I did is NOT the simplest way (and definitely not that fast), and I'm pretty sure it's doable with just one query, if so, the answer is appreciated, and I'm thankful with all of you who tried to help! Apparently I didn't explain myself well. I tried the code you all suggested, and it all works (there's one exception with someone's code, which I'll clarify), but it doesn't serve my purpose. Anyway, here's what I did:
$q = $con->prepare("SELECT id FROM table WHERE f = 1"); //Find the id of the row that has already f = 1
$q->bindColumn(1, $prev_id); //store as $prev_id, it might be useful later
$q->execute();
$q->fetch();
$q = $con->query("UPDATE table SET f = 0 WHERE f = 1"); //Reset row to f = 0
$q = $con->prepare("
UPDATE table
SET f = CASE WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1')
THEN '1'
ELSE f //The original query, IF
END //selected row != 1 on every other
WHERE id = :id //column, then f = 1 on selected id
"); //else, keep previous state (f = 0)
$q->execute(array('id' => "$id"));
$q = $con->prepare("SELECT f FROM table WHERE id = :id");
$q->bindColumn(1, $last_value);
$q->execute(array('id' => "$id")); //Get value of f on last modified id (from previous
$q->fetch(); //query) and store it
if($last_value == 0) //if f = 0, it means the selected id was not modified.
{ //Then, restore f = 1 on the row that previously had it
$q = $con->prepare("UPDATE table SET f = 1 WHERE id = :prev_id");
$q->execute(array('prev_id' => $prev_id));
}
Anyway, thanks to you all, I've learnt a lot today, and it's been fun. Still, I guess this is NOT the best way to do this, and if anyone comes up with a better answer, I'll appreciate it!

please check below:
UPDATE table
SET f =
CASE
WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') THEN
0
WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') THEN
1
ELSE f
END
WHERE ID = :id
But here both the WHEN clause condition are same.

this should work:
UPDATE table
SET f =
CASE
WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1' AND f = '1') THEN
0
WHEN (a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1') THEN
1
ELSE f
END
WHERE ID = :id
The first When clause takes in account the OP's need to set f to 0 when f = 1.

It seems that you don't need an update when a, b, c, d, and e are not equal to 1. In which case, you can use a where clause on your update (and remove the WHERE from your CASE statement):
UPDATE table
SET f =
CASE
WHEN f = 1 THEN 0
ELSE 1
END
WHERE a != '1' AND b != '1' AND c != '1' AND d != '1' AND e != '1'
AND ID = :id;
There's no sense updating f to equal f, as there's no change.
Also, typically a CASE statement follows this format:
CASE
WHEN condition THEN result
WHEN condition THEN result
ELSE default_value
END
See http://dev.mysql.com/doc/refman/5.0/en/case.html (MySQL) and http://www.postgresql.org/docs/9.2/static/functions-conditional.html (PostgreSQL).

Related

PHP query returning only one row out of four

This query was supposed to return me four rows: which are four people with status 50 (which, in the application means "maternity leave"). But it returns only one.
On HeidiSQL the query doesn't even run because it displays a
syntax error on line 13:
(...)
corresponds to your MariaDB server version for the right syntax to use near 'a.id_regiao = '$id_regiao'
AND a.cod_status = 50
AND a.status' at line 13 */"
Here is the query. I'm slowly becoming familiar with sql statements and i did search a lot on SO before asking it:
//SELECTING PROJECT DATA
$query = "SELECT b.id_clt,b.nome AS nome_clt,
a.id_evento AS a_id_evento,a.data AS a_data,a.data_retorno AS a_data_retorno,
c.id_evento AS c_id_evento,c.data AS c_data,c.data_retorno AS c_data_retorno,
(SELECT nome FROM projeto WHERE id_projeto = a.id_projeto) AS nome_projeto,
(SELECT nome FROM curso WHERE id_curso = b.id_curso) AS nome_curso,
DATE_FORMAT(a.data,'%d/%m/%Y') AS a_data_br,
DATE_FORMAT(a.data_retorno,'%d/%m/%Y') AS a_data_retorno_br,
DATE_FORMAT(c.data,'%d/%m/%Y') AS c_data_br,
DATE_FORMAT(c.data_retorno,'%d/%m/%Y') AS c_data_retorno_br
FROM rh_eventos AS a
INNER JOIN rh_clt AS b ON (a.id_clt = b.id_clt AND a.cod_status = 50)
LEFT JOIN rh_eventos AS c ON (b.id_clt = c.id_clt AND c.cod_status = 54)
WHERE $cond_projeto a.id_regiao = '$id_regiao'
AND a.cod_status = 50
AND a.status = 1
AND NOW() BETWEEN a.data AND a.data_retorno
ORDER BY nome_projeto,b.nome;";
The problem is here in the query:
WHERE $cond_projeto a.id_regiao = '$id_regiao'
This inserts a variable (or maybe a full test?) without proper syntax. If it is a variable, include the table's column name in the criterium. If it is a full test, include AND like so:
WHERE $cond_projeto AND a.id_regiao = '$id_regiao'
Beware though! Use prepared statements, your code now appears to be vulnerable to SQL injection attacks (and those are not to be trifled with).
Here is the query, (as seen by using an echo before it) . I can see the output on heidsql now. Now its better for us to check it:
SELECT b.id_clt,b.nome AS nome_clt,
a.id_evento AS a_id_evento,a.data AS a_data,a.data_retorno AS a_data_retorno,
c.id_evento AS c_id_evento,c.data AS c_data,c.data_retorno AS c_data_retorno,
(SELECT nome FROM projeto WHERE id_projeto = a.id_projeto) AS nome_projeto,
(SELECT nome FROM curso WHERE id_curso = b.id_curso) AS nome_curso,
DATE_FORMAT(a.data,'%d/%m/%Y') AS a_data_br,
DATE_FORMAT(a.data_retorno,'%d/%m/%Y') AS a_data_retorno_br,
DATE_FORMAT(c.data,'%d/%m/%Y') AS c_data_br,
DATE_FORMAT(c.data_retorno,'%d/%m/%Y') AS c_data_retorno_br
FROM rh_eventos AS a
INNER JOIN rh_clt AS b ON (a.id_clt = b.id_clt AND a.cod_status = 50)
LEFT JOIN rh_eventos AS c ON (b.id_clt = c.id_clt AND c.cod_status = 54)
WHERE a.id_regiao = '1' AND a.cod_status = 50
AND a.status = 1
AND NOW() BETWEEN a.data AND a.data_retorno ORDER BY nome_projeto,b.nome;
I can now see the output on heidsql, though i still cant figure out why it doesent bring the other thre rows.

WHERE NOT IN AND WHERE error

I tried moving the WHERE clause many times but I'm still having an error. Am I doing the WHERE NOT IN AND WHERE clause wrong? The code is working perfectly fine until I added the WHERE ha_rooms.deleted != 1 clause. I also tried using deleted <> 1 but it still shows the same error
$query2 = $this->db->query("SELECT * FROM ha_rooms
WHERE ha_rooms.deleted != 1 JOIN ha_user_room_merged
WHERE ha_rooms.room_id NOT IN (SELECT ha_user_room_merged.room_id
FROM ha_user_room_merged WHERE ha_user_room_merged.deleted = 0)
group by ha_rooms.room_id");
The error is this
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'JOIN ha_user_room_merged WHERE ha_rooms.room_id NOT IN (SELECT
ha_user_room_merg' at line 1
If I said frankly, your query is not done properly in anyway but it gives pretty much clear vision of what you are trying to do if you don't have any other logic behind that. So, I would like to suggest you to do google for SQL Syntax, Ordering, use of GROUP BY, WHERE sub-query etc. BTW below is the proper version of your query please check if it's useful for you
SELECT hr.*
FROM ha_rooms hr
JOIN ha_user_room_merged hurm On hurm.room_id = hr.room_id
WHERE hurm.deleted = 0
AND hr.deleted <> 1
Use below codeigniter query. in your join there is no ON
$all_ids = 0;
$this->db->select('group_concat(room_id) as ids');
$this->db->where('deleted', 0);
$ids = $this->db->get('ha_user_room_merged')->row_array();
if($ids) {
$all_ids = explode(',', $ids['ids']);
}
$this->db->where('hr.deleted !=', 1);
$this->db->where_not_in('hr.room_id', $all_ids);
$this->db->join('ha_user_room_merged hrm', 'hrm.room_id = hr.room_id');
$this->db->group_by('hr.room_id');
$this->db->get('ha_rooms hr')->result_array();
Please try..
select * from ha_rooms as a inner join ha_user_room_merged b on a.ha_rooms.id = b.room_id
where b.deleted <> 0
Output
ha_rooms.room_id ha_user_room_merged.room_id deleted
1 1 1
2 2 1
3 3 1
4 4 1
Thanks :)

Joomla PHP MySQL Query to use MySQL IF function

So i have a Joomla site and in the joomla documentation I can't find anything to do with MySQL's IF, ELSE function within a query.
The part of the query i need a if statement in MySQL is here.
$query->where($db->quoteName('container').' != 1');
It should be doing something like this :
$query->where('IF '.$db->quoteName('server_number').' != '.$number.' THEN '$query->where($db->quoteName('container').' != 1');' END');
If the $number input does not match with the server_number column data then to add a where statement to the mysql query.
Full MySQL Query :
SELECT a.*,ext.media_type
FROM database_hwdms_processes AS a
LEFT JOIN database_hwdms_media AS media ON media.id = a.media_id
LEFT JOIN database_hwdms_ext AS ext ON ext.id = media.ext_id
WHERE (a.status = 1 || a.status = 3) AND a.attempts < 5 AND `container` != 1 AND
server = 1
ORDER BY a.media_id ASC
Want to add a "IF server_number != 1 THEN WHERE container != 1 END" would mean replacing "AND container != 1"
I figured out a better way to resolve my problem using MySQL's
OR ||
function
So my fixed code became this :
PHP :
$query->where('('.$db->quoteName('server_number').' = '.$number.' || '.$db->quoteName('container').' != 1 )');
In plain MySQL text :
SELECT a.*,ext.media_type
FROM database_hwdms_processes AS a
LEFT JOIN database_hwdms_media AS media ON media.id = a.media_id
LEFT JOIN database_hwdms_ext AS ext ON ext.id = media.ext_id
WHERE (a.status = 1 || a.status = 3) AND a.attempts < 5 AND ( `server_number` = 1 || `container` != 1 )AND
server = 1
ORDER BY a.media_id ASC

SQL multiple selects on same table and column for data filtering

I know I've done this before, but haven't done much SQL in a while.
I have a table called lead_detail, it has the following columns: id, lead_id, form_id, field_number, value.
I'm trying to get results and then filter them.
So, originally, I got all the lead ids that had a particular answer for a particular question.
Let's say the first filter was that I wanted all results for an answer of "yes" to a question of "do you like chicken" (field_number of 4).
$leadIds = query(SELECT lead_id FROM lead_detail WHERE field_number = '4' AND value = 'yes' AND form_id = '1')
$leadIds = implode(', ', $leadIds);
Then, I could get the appropriate filtered data by
SELECT * FROM lead_detail WHERE form_id = '1' and lead_id IN ($leadIds)
This works perfectly.
If I want to add a SECOND filter though, I need to do two queries to the same columns in the same query. I'm thinking I need to do some kind of join with table aliases, or some sub selects, but can't remember how to do it.
So if I needed to know who answered "yes" to a question of "do you like chicken" AND who answered "18-24" on "what is your age", how would I get the appropriate $leadIds?
It'd be something like the combination of
SELECT lead_id FROM lead_detail WHERE field_number = '4' AND value = 'yes' AND form_id = '1'
AND
SELECT lead_id FROM lead_detail WHERE field_number = '5' AND value = '18-24' AND form_id = '1'
An inner join would work for this:
SELECT DISTINCT(ld1.lead_id)
FROM lead_detail ld1
INNER JOIN lead_detail ld2 ON (ld1.lead_id = ld2.lead_id)
WHERE ld1.field_number = '4' AND ld1.value = 'yes' AND ld1.form_id = '1'
AND ld2.field_number = '5' AND ld2.value = '18-24' AND ld2.form_id = '1'
There is possibly a neater solution however.
Couldn't you just use
SELECT lead_id
FROM lead_detail
WHERE ((field_number = '4' AND value = 'yes') OR (field_number = '5' AND value = '18-24')) AND form_id = '1'

How can I make an UPDATE query on INNER JOIN using OR

I want to update the values of one column in a table from '0' to '1', if either of four values in columns in another table are '1'. Somehow this doesn't seem to work and I was just wondering if anyone could help me get the code right or find a different way of doing it if it's not possible,
mysql_query("UPDATE members
INNER JOIN forum_banners ON members.id = forum_banners.userid
SET members.beta = '1' WHERE forum_banners.bebeta = '1' OR
forum_banners.bibeta = '1' OR forum_banners.cbeta = '1' OR
forum_banners.wbeta = '1'") or die(mysql_error());
That's what I tried, but it's not working, I suspect because of the OR. I tried having all updatings in different mysql_query bits, but that didn't work either.
You should be able to update from multiple table references. This is untested, but gives you an idea:
UPDATE
members, forum_banners
SET
members.beta = '1'
WHERE
members.id = forum_banners.userid
AND forum_banners.bebeta = '1'
OR forum_banners.bibeta = '1'
OR forum_banners.cbeta = '1'
OR forum_banners.wbeta = '1'
http://dev.mysql.com/doc/refman/5.0/en/update.html
Note "Multi-Table syntax"
Try
UPDATE
m
SET
m.beta = '1'
FROM
members m
INNER JOIN
forum_banners fb
ON m.id = fb.userid
WHERE
fb.bebeta = '1'
OR fb.bibeta = '1'
OR fb.cbeta = '1'
OR fb.wbeta = '1'"
Aliases also help make your syntax a little neater.

Categories