This question already has answers here:
MySQL query finding values in a comma separated string
(11 answers)
Closed 5 years ago.
I have field in MySQL table. The field is called 'vehicles' When I add vehicles I add them by ID not name, so the field is populated like '2:3:4:6:7:9' 2 will be a car, 7 will be a bike, etc.
What I want to do quickly and simply is when I query the table I want to see if the field vehicle contains '2' is in that field within the 2:3:4:7:9.
I have tried a lot but coming up blank?
Thanks
if you just want to locate any specific number then do like this
$data = "2:3:4:6:7:9";
echo "found on index : " . array_search("2", explode(":", $data));
You can use FIND_IN_SET in quer query like
SELECT *
FROM yourTable
WHERE FIND_IN_SET('2',REPLACE(vehicle ,':',',')) > 0;
samples
mysql> SELECT FIND_IN_SET('1',REPLACE('2:3:4:7:9',':',',')) as a;
+------+
| a |
+------+
| 0 |
+------+
1 row in set (0,00 sec)
mysql> SELECT FIND_IN_SET('2',REPLACE('2:3:4:7:9',':',',')) as a;
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0,00 sec)
mysql> SELECT FIND_IN_SET('7',REPLACE('2:3:4:7:9',':',',')) as a;
+------+
| a |
+------+
| 4 |
+------+
1 row in set (0,00 sec)
mysql> SELECT FIND_IN_SET('8',REPLACE('2:3:4:7:9',':',',')) as a;
+------+
| a |
+------+
| 0 |
+------+
1 row in set (0,00 sec)
Related
In my inherited database, sometimes binary questions are encoded as ('Yes', 'No'), and sometimes as (1,0). I mistakenly queried against the string 'Yes' on a field which was numerically encoded. My guess is that the string was turned into a '0' by MySQL.
I have a query like this:
SELECT `children_under_18`
FROM `households`
WHERE `children_under_18` = 'Yes'
GROUP BY `children_under_18`
It ended up only matching records where children_under_18 was 0, the opposite of what I wanted. I know I need to be more careful. I am looking for a definitive answer as to what happened.
String is always converted to 0 when compared to numeric (of course string containing numeric + string is converted numeric. but this is not good practice)
mysql> SELECT 'Yes' + 0;
+-----------+
| 'Yes' + 0 |
+-----------+
| 0 |
+-----------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-----------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'Yes' |
+---------+------+-----------------------------------------+
If you want store binary value (Yes/No or True/False) or small value set, ENUM is good choice.
It takes small disk space and can use meaningful String.
mysql> CREATE TABLE enum_test(a ENUM('Yes', 'No'));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into enum_test values('Yes'), ('No'), ('Invalid');
Query OK, 3 rows affected, 1 warning (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 1
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'a' at row 3 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> select * from enum_test where a = 'Yes';
+------+
| a |
+------+
| Yes |
+------+
1 row in set (0.00 sec)
mysql> select * from enum_test where a = 'No';
+------+
| a |
+------+
| No |
+------+
1 row in set (0.00 sec)
So, I have 2 tables.
One is books, that has the following fields.
accno(Accession number), name(book name), status(Issued/Not Issued)
Second is total, that has the following fields.
name(book name), count(Number of books that are 'Not Issued' in the books table
I have a form that adds books in the books table, and the default status is 'Not Issued'.
I also have a form that issued books i.e. it changes the status to 'Issued'.
And I have a form that returns the books i.e. it changes the status back to 'Not Issued'.
I'm looking for a trigger that updates the count in the total table everytime the bookstable is updated. Count is the number of books that are available(Not Issued) in the books table, and it is different for different books(book names).
I am totally new to triggers. I have looked arond, but I can't seem to figure a way to implement this.
Any help is appreciated. Thank you.
Looks like its an inventory system, so every time a new book comes into the library you store the inventory number into the total table and when a book is issued against the accnum the inventory is decreased by one and then its returned its increased by one.
In this case the following trigger should do the job
delimiter //
create trigger book_available after update on books
for each row
begin
if new.status = 'Issued' then
update total set `count` = `count` - 1 where name = new.book_name ;
else
update total set `count` = `count` + 1 where name = new.book_name ;
end if ;
delimiter ;
Here is a test case
mysql> select * from books ;
+--------+-----------+------------+
| accnum | book_name | status |
+--------+-----------+------------+
| 1 | AA | Not Issued |
| 2 | AA | Issued |
| 3 | BB | Not Issued |
+--------+-----------+------------+
3 rows in set (0.00 sec)
mysql> select * from total ;
+------+-------+
| name | count |
+------+-------+
| AA | 20 |
| BB | 30 |
+------+-------+
2 rows in set (0.00 sec)
mysql> delimiter //
mysql> create trigger book_available after update on books
-> for each row
-> begin
-> if new.status = 'Issued' then
-> update total set `count` = `count` - 1 where name = new.book_name ;
-> else
-> update total set `count` = `count` + 1 where name = new.book_name ;
-> end if ;
-> end ;//
Query OK, 0 rows affected (0.13 sec)
mysql> delimiter ;
mysql> update books set status = 'Issued' where accnum = 1 ;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from total ;
+------+-------+
| name | count |
+------+-------+
| AA | 19 |
| BB | 30 |
+------+-------+
2 rows in set (0.00 sec)
mysql> update books set status = 'Not Issued' where accnum = 1 ;
Query OK, 1 row affected (0.04 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from total ;
+------+-------+
| name | count |
+------+-------+
| AA | 20 |
| BB | 30 |
+------+-------+
2 rows in set (0.00 sec)
When i am running a query, for example:
"SELECT * FROM program_detaljer where program_ref_id='a'"
All I get from the result is program_ref_id = 0.
Why does this happen, when the program_ref_id column is supposed to be int(11)?
You should read about types conversion in mysql
Before comparison mysql tries to convert string ('a') to number ('0').
mysql> SELECT 0='a';
+-------+
| 0='a' |
+-------+
| 1 |
+-------+
1 row in set, 1 warning (0.00 sec)
You could check value before quering. Or replace = with LIKE : ). (But better to check value type before.)
mysql> SELECT 0 LIKE 'a';
+------------+
| 0 LIKE 'a' |
+------------+
| 0 |
+------------+
1 row in set (0.00 sec)
I'm doing a work for a client but since I haven't been using PHP/MySQL for a while I forgot some simple things, hope you can help me out.
I have the following SQL table:
ID (non-null, autoincrement) | credit (int)
My query should put the whole "credit" column to 0 except for the row that has the higher ID.
So I would do:
UPDATE $table SET credit = 0 WHERE... ?
Thanks in advance for any help :)
UPDATE $table SET credit = 0 WHERE ID > $ID
Will update any rows that have and ID greater than the variable $ID
If you only want to update the row with the maximum ID then use:
UPDATE $table SET credit = 0 WHERE ID = (select max(id) from $table)
Edit: As Eggyal correctly points out MySQL doesn't like a subquery on the same table as an update - but you can get around it nicely:
UPDATE $table
SET credit = 0
WHERE
credit='$credit'
AND statid='$statid'
AND userid='$userid'
AND ID = (select ID from (SELECT MAX(ID)as ID from $table) a)
And examples from my console:
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | eeee |
+------+-------+
5 rows in set (0.00 sec)
mysql> update first set title='ffff' where id=(select max(id) from first);
ERROR 1093 (HY000): You can't specify target table 'first' for update in FROM clause
mysql> update first set title='ffff' where id=(select ID from (select max(id) as ID from first) a);
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | ffff |
+------+-------+
5 rows in set (0.00 sec)
Note: As the subquery within a subquery trick unlocks the original table, it is a good idea to run this within a transaction - if the table is unlocked from a query, it might have changed by the time it is updated - so it will be a good idea to use this type of query within a transaction.
Hi i'm working on some code with mysql and need to display the mysql results with php..
MySQL
select distinct(year(Cataloged_Date)) from records;
+------------------------+
| (year(Cataloged_Date)) |
+------------------------+
| 2009 |
+------------------------+
1 row in set (0.00 sec)
PHP
foreach($query->result() as $show){
$data[$i] = $show->Cataloged_Date;
$i++;
}
I'm using codeigniter for the php. Using $show->Cataloged_Date will not return anyting. I'm thinking its $show-> something to display the results...Just cant get it right now...
You need to provide a explicit name or alias for your field in the mysql query - when you apply functions to a column then it's non-obvious what the column name will be.
Try this:
//on MySQL
select distinct(year(Cataloged_Date)) as "Cat_Date" from records;
<?php
foreach($query->result() as $show){
$data[$i] = $show->Cat_Date;
$i++;
}
?>
You can apply an alias to any "value" on your select, be it a column name or the result of a function.
Just do
SELECT something AS YourAlias ...
To give you a clear example:
mysql> select 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
#A simple value can be given an alias
mysql> select 1 as "Number";
+--------+
| Number |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
mysql> select max(val) from my_values;
+----------+
| max(val) |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
#A function
mysql> select max(val) as "max_val" from my_values;
+---------+
| max_val |
+---------+
| 4 |
+---------+
1 row in set (0.00 sec)
#or even a plain column
mysql> select val as "lav" from my_values;
+------+
| lav |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
4 rows in set (0.00 sec)
Yes this is normally true but i'm using Codeigniter php framework. I did get it working with
$query->first_row() as $show
Then just echo $show and the results will display without you needing to know the rows name..