The first query i am making is for all of the Id's associated with a user:
$DBH = getDBH();
$stmt = $DBH->prepare("SELECT id FROM list WHERE user = ?");
$stmt->bind_param("s",$userid);
$stmt->execute();
$stmt->bind_result($ids);
$stmt->fetch();
$stmt->close();
currently stored in the table is as follow:
ID user
1 example
4 example
7 example
15 example
The id's are not known before the query and the amount of id's associated with the user will be continuously growing and shrinking.
So my question is how can i query for these id's and stick them into a string with each id separated by a comma
ex:
1,4,7,15, etc, etc.
EDIT: USING GROUP CONCAT()
$stmt = $DBH->prepare("SELECT GROUP_CONCAT(id) as id FROM list WHERE user = ? GROUP BY id");
$stmt->bind_param("s",$userid);
$stmt->execute();
$stmt->bind_result($id);
Take a look at group_concat() function
Plese note that the max length that the string can take is specified by group_concat_max_len() variable and by default is 1024 chars.
You can see yours with this query
show variables like 'group%'
Related
I have a column in my database table called "name" and it stores the users names as "FirstName LastName". I want the query to return the members ordered alphabetically by their last names.
$sql = 'SELECT * FROM members ORDER BY name';
$stmt = $pdo->prepare($sql);
$stmt->execute();
$members = $stmt->fetchAll(PDO::FETCH_ASSOC);
This doesn't work since the result is ordered by the whole name field and not the last name only. How could I fix this?
Thank you.
You may order using SUBSTRING_INDEX:
SELECT *
FROM members
ORDER BY SUBSTRING_INDEX(name, ' ', -1);
By the way, it is generally bad table design to store the first and last name in the same column. It would be much better to have two separate columns for the first and last names.
Here's my usual way of counting rows...
$query = "SELECT * FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$count = $stmt->rowCount();
This will count all rows, even if I use a WHERE clause, it'll still count every row that meets that condition. However, let's say I have a table, we'll call it tokensEarned (that's my actual table name). I have the following data...
user_id = 1,2,4,5,8,8,2,4,3,7,6,2 (those are actual rows in my table - clearly, user 1 has 1 entry, 2 has three entries, etc.) In all, I have 12 entries. But I don't want my query to count 12. I want my query to count each user_id one time. In this example, my count should display 8.
Any help on this? I can further explain if you have any specific questions or clarification you need. I would appreciate it. Thank You.
The following query will yield the distinct user count:
$query = "SELECT COUNT(DISTINCT user_id) AS cnt FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo "distinct user count: " . $row['cnt'];
It isn't possible to get all records and the distinct count in a single query.
Whether you use the query above or you return all the actual distinct rows really depends on whether you need the full records. If all you need are the counts, then it is wasteful to return the data in the records, and what I gave above is probably the best option. If you do need the data, then selecting all distinct rows might make more sense.
You can use distinct in mysql to select only unique fields in your table.
$query = "SELECT distinct user_id FROM users";
$stmt = $db->prepare($query);
$stmt->execute();
$count = $stmt->rowCount();
Change your query to the following, this way you only shows the unique user_id:
$query = "SELECT DISTINCT user_id FROM users";
I'm building a QueryBuilder where you can insert dynamically, after that I would like to return the last row inserted, so far I'm getting the last inserted Id with pdo.
$last_id = $this->pdo->lastInsertId();
After that i need to do a query
$statement = $this->pdo->prepare("SELECT * FROM {$table_name} WHERE id = :id");
The problem is that my column
Id
Doesn't call like that all the time, sometimes it name is id_user or id_work, etc.
What i need is to get the column name of where PDO is getting the last Id.
No direct way to know the field name, and there are two solutions.
1) If less tables, you can build an array to save the "id" field directly. for example :
$tables = ["table_1" : "id_user", "table_2" : "id_work"]
and you can use the $tables[$table_name] instead of the id in your SQL.
2) If you don't know which tables will be used, you can analysis the table directly via PDO before you generate the query sql.
For example
$stmt = $pdo->prepare('DESC tablename');
$stmt->execute();
$table_fields = $stmt->fetchAll(PDO::FETCH_COLUMN);
foreach($table_fields as $field){
if($field["Extra"] == "auto_increment"){
$field_id_name = $field["Field"];
break;
}
}
If I have a table with 3 rows with IDs 1,3,5 because rows with ID 2 and 4 were deleted, how do I make sure I select a row that exists?
$stmt = $db->prepare("SELECT COUNT(*) FROM table");
$stmt->execute();
$stmt->bind_result($numRows);
$stmt->fetch();
$stmt->close();
$random = mt_rand(1,$numRows);
$stmt = $db->prepare("SELECT link FROM table WHERE id=$random");
This won't ever select row with id 5, and also will select one that doesn't exist (2).
If the number of rows are small (and you are sure that it will stay that way), you can use ORDER BY RAND()
(Please note that this will create performance problems with big tables).
Other way is first counting how many rows are there
SELECT COUNT(*) AS total FROM table;
then pick a random number
$rand = rand(1, $total);
and select that row with limit
SELECT * FROM table LIMIT $rand, 1;
U can use a SQLstatement with EXISTS
SELECT link
FROM table
WHERE EXISTS (SELECT link
FROM table
WHERE id = $random);
If you just want a random row and don't care about the id, then you could use:
SELECT link FROM table
ORDER BY RAND()
LIMIT 1
For large numbers of rows (10000+), then you may need to implement another solution, as this query can be slow. This site has a good explanation and alternative solutions
If you want to follow your approach then you have to do some changes in your query.
1.) Query one : select id from table. // It will give you array of existing id.
2.) You have to use array_rand(). and use your second query.
Example :
$stmt = $db->prepare("SELECT ID FROM table");
$result = $stmt->fetchAll();
$random = array_rand(array_flip($result), 1);
$stmt = $db->prepare("SELECT link FROM table WHERE id=$random");
You could select one, randomly order, like this:
SELECT link FROM table ORDER BY RAND() LIMIT 1
UPDATE:
You should benchmark the different solutions you have, but I'm thinking this one could be nice with large amount of rows:
$stmt = $db->prepare("SELECT COUNT(*) FROM table");
$stmt->execute();
$stmt->bind_result($numRows);
$stmt->fetch();
$stmt->close();
$random = mt_rand(1,$numRows);
$stmt = $db->prepare("SELECT link FROM table WHERE id>=$random LIMIT 1");
$stmt->execute();
$stmt->bind_result($link);
if(!$link){
$stmt = $db->prepare("SELECT link FROM table WHERE id<$random LIMIT 1");
$stmt->execute();
$stmt->bind_result($link);
}
Is there a method to get last select ID in a similar way to lastInsertId?
For example:
<?php
$stmt = $db->prepare('SELECT * FROM users WHERE user_id = :user_id');
$stmt->bindValue(':user_id', $_GET['id'], PDO::PARAM_INT);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_OBJ);
$user_id = $db->lastSelectId('user_id'); // what can I do here?
?>
Obviously in the above example I could simply get the last selected row ID with $user->user_id but that's not the question. Any ideas?
If you want to select the last inserted row from your database table, there is no point selecting all rows and then looking for the last in a loop. Besides, user_id should be primary key, in which case you query should only return one row.
If user_id is an auto-incremented field, your query should go like SELECT * FROM users ORDER BY user_id DESC LIMIT 1, this will return the user with the largest user_id.
I will also suggest the you save the timestamp of when users are inserted and then you can do ORDER BY date_added DESC LIMIT 1 this will work irrespective of the ORDER of the user_ids.
No, there is no other way than reading $user->user_id. No magic functions to get the last id of a select.
And it's probably because there is no need for it, since the select returns that value itself. You've shown in your question how easy it is to read the id.
Try With following -
$stmt->insert_id;
Refer the below link -
Using PHP, MySQLi and Prepared Statement, how I return the id of the inserted row?
Make sure you use LIMIT 1 if you're searching for one specific user.
$stmt = $db->prepare('SELECT * FROM users WHERE user_id = :user_id LIMIT 1');
$stmt->bindValue(':user_id', $_GET['id'], PDO::PARAM_INT);
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_OBJ);
echo $user->user_id;
Here are my solutions :
Put the desired ID of the last SELECT in the $_SESSION['name'].
Put it in the html file as a Hidden Input.
Go fetch it at the beginning of you controller file so it's always set and ready to use.
Use lastInsertId();