Issue when using concat with commas - php

I have a table with values, primary keys are unique ids with increment.
Secondly I have another table that saves the ids from the first table along with other data. The ids are stored in a already_used column
the already_used column should look like this: 1,2,3,4,5,6....
Now I use a query with CONCAT to fill the already_used column with data:
UPDATE table2 SET already_used = CONCAT(already_used,', ". $id ."') WHERE id = $table_id
Now my problem is that if the already_used column is empty, concat will produce an output like this: ,1,2,3,4,5,6...
So there is a comma in front of the first value. How can I ajust the query so the first value doesn't actually get a comma in front of it?
Later I store the already_used data in a variable using PHP and then I want to find all rows from table1 that weren't already used using a NOT IN statement:
SELECT * FROM table1 WHERE id NOT IN($variable)
And if there's a comma in front it will give a mysql error.

Never store multiple values in a single column. Never!
Please change your DB desgin to store only one id per record in table2.

Use IF or CASE to test already_used before concatenating:
UPDATE table2
SET already_used = IF(already_used = '', '$id', CONCAT(already_used, ',$id'))
WHERE id = $table_id
In your second query, you should use FIND_IN_SET:
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
ON FIND_IN_SET(t1.id, t2.already_used)
WHERE t2.id IS NULL
However, FIND_IN_SET can't be indexed. This is why a relation table is usually a much better design.

UPDATE table2 WHEN already_used IS NULL THEN SET already_used = CONCAT(already_used,'". $id ."') WHEN already_used IS NOT NULL THEN SET already_used = CONCAT(already_used,', ". $id ."') WHERE id = $table_id

Related

How to ignore null value while fetching the data from database table php mysql

How to ignore null value while fetching the data from database table php mysql. Anyone please help me
My mysql query is :
$sql = "SELECT DISTINCT cuid FROM temp_donor_list WHERE donor_no='$name'";
Try this below code
$sql = "SELECT DISTINCT cuid FROM temp_donor_list WHERE donor_no='$name' and cuid!='' and donor_no!=''";
If your field contains NULL value then you can use IS NOT NULL condtion.
If your field contains blank string then you can use <> opertor
SELECT DISTINCT cuid FROM temp_donor_list WHERE donor_no='$name' AND cuid IS NOT NULL AND cuid<>''

mysql insert record not immediately available, select count(*) doesn't see it right away

In my php code, I have a Mysql query:
SELECT COUNT(*)
to see if the record already exists, then if it doesn't exist I do an:
INSERT INTO <etc>
But if someone hits reload with a second or so, the SELECT COUNT(*) doesn't see the inserted record.
$ssql="SELECT COUNT(*) as counts FROM `points` WHERE `username` LIKE '".$lusername."' AND description LIKE '".$desc."' AND `info` LIKE '".$key."' AND `date` LIKE '".$today."'";
$result = mysql_query($ssql);
$row=mysql_fetch_array($result);
if ($row['counts']==0) // no points for this design before
{
$isql="INSERT INTO `points` (`datetime`,`username`,`ip`,`description`,`points`,`info`, `date`,`uri`) ";
$isql=$isql."VALUES ('".date("Y-m-d H:i:s")."','".$lusername."',";
$isql=$isql."'".$_SERVER['REMOTE_ADDR']."','".$desc."','".$points."',";
$isql=$isql."'".$key."','".$today."','".$_SERVER['REQUEST_URI']."')";
$iresult = mysql_query($isql);
return(true);
}
else
return(false);
I was using MyISAM database type
Instead of running two seperate queries just use REPLACE INTO.
From the documentation:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
For example if your key field is id then:
REPLACE INTO my_table SET id = 4 AND other_field = 'foobar'
will insert if there is no record with id 4, or if there is then it will replace the other_field value with foobar.

MYSQL - append or insert value into a column depending on whether it's empty or not

As title says, im trying to append a string to a VARCHAR column in my table.
The string is something like " //string ", forward slashes will be used later to explode the string to an array in PHP.
I was wondering if there's a way in MYSQL to perform a CONCAT(columnname, "//string") if the column is empty, otherwise perform a normal UPDATE ... SET ... WHERE . In this way, i will avoid the first value of my future exploded string to be a "//string" with forward slahes.
also, above I 've used bold characters for "in MYSQL" because I know i could first query the DB (to check if the column is empty) with something like:
$q = $conn->dbh->prepare('SELECT columnname FROM tablename WHERE username=:user');
$q->bindParam(':user', $username);
$q->execute();
$check = $q->fetchColumn();
and then leave PHP decide which operation perform:
if ($check != '') { // PERFORM A CONCAT }
else { // PERFORM AN UPDATE }
but this would mean a waste of time/resources due to 2x database calls and more PHP code.
thanks.
https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
That means in your case:
INSERT INTO tablename (id,columnname) VALUES (1,'//string')
ON DUPLICATE KEY UPDATE columnname=CONCAT(columnname,'//string');
http://sqlfiddle.com/#!9/bd0f4/1
UPDATE Just to show you your options:
http://sqlfiddle.com/#!9/8e61c/1
INSERT INTO tablename (id, columnname) VALUES (1, '//string')
ON DUPLICATE KEY UPDATE columnname=CONCAT(columnname,'//string');
INSERT INTO tablename (id, columnname) VALUES (1, '//string')
ON DUPLICATE KEY UPDATE columnname=CONCAT(columnname,'//string');
INSERT INTO tablename (id, columnname) VALUES ((SELECT id FROM tablename t WHERE columnname='blahblah'), '//string')
ON DUPLICATE KEY UPDATE columnname=CONCAT(columnname,'//string');
INSERT INTO tablename (id, columnname) VALUES ((SELECT id FROM tablename t WHERE id=2), '//string')
ON DUPLICATE KEY UPDATE columnname=CONCAT(columnname,'//string');
INSERT INTO tablename (id, columnname) VALUES ((SELECT id FROM tablename t WHERE columnname='newone'), '//newone')
ON DUPLICATE KEY UPDATE columnname=CONCAT(columnname,'//newone');
If what you want is this:
first string: column will contain 'firststring'
second string: column will contain 'firststring//secondstring'
then do the update like this:
UPDATE tablename SET columnname = CONCAT( IF(IFNULL(columnname,'')='','',CONCAT(columnname,'//')), :string) WHERE username=:user

determine if mysql values are in same row

How would this be done? I would like to search the database row by row. I might even print out the entire list of the database row by row. But I would also like to show record 1400 for example and determine the info on that row - such as name, gender and country.
Is it possible to use the rownum function to get this done? Or would I need to use a where in the query? But even so how would I determine the row number? Thanks.
Make one column as ID, make it PK and auto_increment. Then your query shell be something like this for #1400 row:
$pdo
->prepare(
"SELECT `name`, `gender`, `country`
FROM `foo_table` WHERE `id` = :id"
)
->execute([':id' => 1400]);
You can use user defined variables to get your rownumber in MySQL
set #nr = 0;
Now you can use this variable (same connection!) in your query
SELECT
#nr := (#nr + 1) rownumber,
*
FROM
table
see: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
do your select and add
LIMIT n,1
this will skip to n-th element(1400) and show just one result

get columns default values as they are a row of a resultset

is there a way to get default values of columns as they are a row of a resultset?
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`state` tinyint(2) NOT NULL DEFAULT '22',
`pubdate` datetime NOT NULL DEFAULT '2012-01-01 00:00:00',
for instance a table like this should return this record:
id->NULL (?)
state->22
pubdate->2012-01-01 00:00:00
in practice, when some user opens edit.php?id=44 he will get the row 44 (update mode), but if he opens edit.php?id=0 (insert mode) I want that the fields contain default values as place holders
thank you in advance
There is a DEFAULT function
SELECT DEFAULT( id ) , DEFAULT( EXAMPLE ) FROM test LIMIT 1
With above query, it seems that you need to have atleast one record in the table as it returns no records otherwise. For current timestamp, it return a timestamp formatted string of 0s.
Sure, using the information_schema database (which stores all the information about your database structure), you can do something like:
SELECT
COLUMN_NAME,
COLUMN_DEFAULT
TABLE_NAME
FROM information_schema.COLUMNS
WHERE
TABLE_NAME='your_table_name'
AND TABLE_SCHEMA='your_database_name'
If you have a limited number of columns, you can collect them into a row using a construct like:
SELECT
id.defaultval AS id_default,
state.defaultval AS state_default,
pubdate.defaultval AS pubdate_default
FROM
(SELECT TABLE_NAME, COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='id') id
JOIN (SELECT COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='state') state ON id.TABLE_NAME = state.TABLE_NAME
JOIN (SELECT COLUMN_DEFAULT AS defaultval FROM information_schema.COLUMNS WHERE TABLE_NAME='your_table' AND TABLE_SCHEMA='your_database' AND COLUMN_NAME='pubdate') pubdate ON id.TABLE_NAME = pubdate.TABLE_NAME
Use DESCRIBE http://dev.mysql.com/doc/refman/5.0/en/describe.html
DESCRIBE sometable [somefield]
Here is php example for single field:
$resource = mysql_query("DESCRIBE sometable somefield");
$schema = mysql_fetch_assoc($resource);
$default = $schema['default'];
And here is the php example for few fields:
$resource = mysql_query("DESCRIBE sometable");
while ($schema = mysql_fetch_assoc($resource)) {
$default_list[$schema['Field']] = $schema['Default'];
}
I see no use for such a behavior and find it wrong.
It is not convenient to use. Imagine I want to enter my own state value. I'd have to delete default 22 first.
Even worse with date. Instead of setting current datetime, you are going to make me edit whole date. Why?
And for the id it is just impossible.
Why can't you just check the input fields and if empty - not to insert at all, letting database set these defaults
You just overthinked it, I believe.

Categories