PHP MySQL Randomize three columns together? - mysql

I've written a basic name randomizer (below) which works fine to pull 3 random first names.
<?php
$sql = "
SELECT *
FROM newNamesTable
WHERE newNamesId
ORDER
BY rand()
LIMIT 3;
";
$result = mysqli_query($conn, $sql);
$rowCount = mysqli_num_rows($result);
if ($rowCount > 0) {
while($row = mysqli_fetch_assoc($result)){
echo "<p class=\"resultname\">" . $row['firstNames'] . "</p>";
}
} else {
echo "No results found.";
}
?>
However, my table contains middle and last names as well. I am trying to write a code that pulls 3 random entries from each column and arranges them together. I've tried several variations of the code, but can't seem to wrap my head around it.
As a rough table example:
| newNamesId | firstNames | midNames | lastNames |
| ---------- | ---------- | -------- | --------- |
| 1 | Steve | James | Doe |
| 2 | Dave | John | Ray |
| 3 | Pete | Jim | Me |
| 4 | Paul | Jason | Fa |
| 5 | Bill | Justin | So |
I would like the code to mix these names together, so a result might be "Bill James Me" or "Paul Jim So"
Thanks in advance!

Related

Laravel sub-query

I have a database that looks like this:πŸ‘‡πŸ‘‡
images πŸŒ…
| id | name | src | status |
| ------------- |---------------| ------------| ----------|
| 1 | nice sun set | 1020288.jpg | published |
| 2 | poor sun set | 1120288.jpg | published |
| 3 | best sun set | 3120288.jpg | deleted |
| ------------- |---------------| ------------| --------- |
image_views πŸ‘€
| id | image_id | browser_id🌎 | created_at |
| ------------- |---------------| ------------ | ------------------ |
| 1 | 2 | 1020288e3221 |2020-02-23 13:55:11 |
| 2 | 1 | 1120288221ww |2020-02-27 13:50:51 |
| ------------- |---------------| ------------ | ------------------ |
Now in my laravel App,
I want to get the most viewed image in the PAST last 7 days.
( i want to have a column of image_views and those views πŸ‘€ should be grouped by browser id ).
so here is what i have tried:πŸ‘‡πŸ‘‡
$image_views = DB::table('image_views')
->selectRaw('count(*) as view_count')
->where(function($query){
$query->where('image_views.image_id', 'images.id');
$query->whereDate('image_views.created_at', '>=', Carbon::now()->subDays(7)->toDateTimeString() );
});
$image = Image::select(['images.*', DB::raw('(' . $image_views->toSql() . ') as views ')])
->limit(1)
->orderBy('views', 'desc')
->where('images.status','published')
->mergeBindings($image_views)
->get();
return $image;
So unfortunately the posted above☝☝ code does not work😩
It only return blank results.
By the way i have lot of views in image_views table starting from 2⃣0⃣1⃣9⃣ to now, just that i couldn't post all here..
THE FUNNY THING IS THAT IF I CONVERT IT TO SQL AND PASTE IT IN PHPMYADMIN IT WORKS LIKE A CHARM
return $image->toSql();
//->mergeBindings($image_views)
//->get();
PLEASE SOMEONE TELL ME WHAT I AM DOING WRONG IN LARAVEL!!πŸ™Œ
Given images & image_views tables
$mostViewdImage = DB::table('image_views')
->join('images', 'image_views.image_id', '=', 'images.id')
->select('browser_id', DB::raw('count(image_id) as occurrence'), 'images.*')
->where('image_views.created_at', '>=', Carbon::now()->subDays(7)->toDateTimeString())
->groupBy('image_id', 'browser_id')
->orderByRaw('occurrence DESC')->first();
dump($mostViewdImage);
//Output
"select `browser_id`, count(image_id) as occurrence, `images`.* from `image_views` inner join `images` on `image_views`.`image_id` = `images`.`id` where `image_views`.`created_at` >= ? group by `image_id`, `browser_id` order by occurrence DESC limit 1" (2.02 s)
{#261 β–Ό
+"browser_id": "1020288e3221"
+"occurrence": 2
+"id": 2
+"name": "poor sun set"
+"src": "1120288.jpg"
+"status": "published"
}

How to add incremental values to mysql database after sorting entries

ID | LastName | FirstName | Ordered
1 | Smith | John |
2 | Smith | Larry |
3 | Jones | Fred |
4 | Johnson | Todd |
Desired result: Update the Ordered field with incremental values in alphabetical order.
1 | Smith | John | 3
2 | Smith | Larry | 4
3 | Jones | Fred | 2
4 | Johnson | Todd | 1
$result = mysql_query("SELECT * FROM MyDatabase ORDER by
LastName,FirstName");
$N=0;
while ($row = mysql_fetch_array( $result ))
{
mysql_query("
UPDATE MyDatabase
SET Ordered = $N + 1
WHERE ...");
}
I know I need the WHERE but I can't seem to make any WHERE clauses work. I always end up with all the same numbers in the Ordered field. What would make this work as intended?
Sounds like you first need to get a total count of all rows in the result set (since you're storing from high to low you need to know the high). Then just decrement that value during the UPDATE / loop
Well, I figured this out to make it work. Just need to fetch the row and then compare it to the ID field as follows:
$result = mysql_query("SELECT * FROM MyDatabase ORDER by LastName, FirstName");
$N=1;
while ($row = mysql_fetch_array( $result ))
{
$updateid = $row['ID'];
mysql_query("
UPDATE MyDatabase
SET Ordered = $N
WHERE ID='$updateid'");
$N++;
}

Count and select all dates for a specific field in MySQL

i have a data format like this:
+----+--------+---------------------+
| ID | utente | data |
+----+--------+---------------------+
| 1 | Man1 | 2014-02-10 12:12:00 |
+----+--------+---------------------+
| 2 | Women1 | 2015-02-10 12:12:00 |
+----+--------+---------------------+
| 3 | Man2 | 2016-02-10 12:12:00 |
+----+--------+---------------------+
| 4 | Women1 | 2014-03-10 12:12:00 |
+----+--------+---------------------+
| 5 | Man1 | 2014-04-10 12:12:00 |
+----+--------+---------------------+
| 6 | Women1 | 2014-02-10 12:12:00 |
+----+--------+---------------------+
I want to make a report that organise the ouptout in way like this:
+---------+--------+-------+---------------------+---------------------+---------------------+
| IDs | utente | count | data1 | data2 | data3 |
+---------+--------+-------+---------------------+---------------------+---------------------+
| 1, 5 | Man1 | 2 | 2014-02-10 12:12:00 | 2014-04-10 12:12:00 | |
+---------+--------+-------+---------------------+---------------------+---------------------+
| 2, 4, 6 | Women1 | 3 | 2015-02-10 12:12:00 | 2014-03-10 12:12:00 | 2014-05-10 12:12:00 |
+---------+--------+-------+---------------------+---------------------+---------------------+
All the row thath include the same user (utente) more than one time will be included in one row with all the dates and the count of records.
Thanks
While it's certainly possible to write a query that returns the data in the format you want, I would suggest you to use a GROUP BY query and two GROUP_CONCAT aggregate functions:
SELECT
GROUP_CONCAT(ID) as IDs,
utente,
COUNT(*) as cnt,
GROUP_CONCAT(data ORDER BY data) AS Dates
FROM
tablename
GROUP BY
utente
then at the application level you can split your Dates field to multiple columns.
Looks like a fairly standard "Breaking" report, complicated only by the fact that your dates extend horizontally instead of down...
SELECT * FROM t ORDER BY utente, data
$lastutente = $lastdata = '';
echo "<table>\n";
while ($row = fetch()) {
if ($lastutente != $row['utente']) {
if ($lastutente != '') {
/****
* THIS SECTION REF'D BELOW
***/
echo "<td>$cnt</td>\n";
foreach ($datelst[] as $d)
echo "<td>$row[data]</td>\n";
for ($i = count($datelst); $i < $NumberOfDateCells; $i++)
echo "<td> </td>\n";
echo "</tr>\n";
/****
* END OF SECTION REF'D BELOW
***/
}
echo "<tr><td>$row[utente]</td>\n"; // start a new row - you probably want to print other stuff too
$datelst = array();
$cnt = 0;
}
if ($lastdata != $row['data']) {
datelst[] = $row['data'];
}
$cnt += $row['cnt']; // or $cnt++ if it's one per row
}
print the end of the last row - see SECTION REF'D ABOVE
echo "</table>\n";
You could add a GROUP BY utente, data to your query above to put a little more load on mysql and a little less on your code - then you should have SUM(cnt) as cnt or COUNT(*) as cnt.

sort a field in my table in MySQL

I have a set of data like this:
ID | Name | Code
1 | John | ygkj
2 | Mike | ghyy
3 | Jay | uuja
And I want to use a function/stored procedure to change the "Code" column into the following:
ID | Name | Code
1 | John | gjky
2 | Mike | ghyy
3 | Jay | ajuu
Or maybe throwing it as a result of a SELECT statement. How can I do it with MySQL?
Thanks!!
Finally, I've done it via PHP. If anyone needs it, I'll post my script here
$inorder = array();
$result = $mysqli->query("select ID, Code from top");
while ($line = $result->fetch_assoc()) {
$stringParts = $line['Code'])
sort(str_split($stringParts);
$inorder[$line['ID']] = implode('',$stringParts);
}
foreach($inorder as $k=>$l)
{
$mysqli->query("update codes SET Code = '".$l."' where id_top = ".$k);
}
It seems like MySQL doesn't have complex array operations to work with the data within the results.

mysql group rows in joined query

Im stumbling upon a problem where i need to retrieve data from the following tables
events
+-------+---------+---------+
| e_id | e_title | e_link |
+-------+---------+---------+
| 1 | Event 1 | event_1 |
| 2 | Event 2 | event_2 |
| 3 | Event 3 | event_3 |
| 4 | Event 4 | event_4 |
| 5 | Event 5 | event_5 |
+-------+---------+---------+
reservations
+-------+---------+---------+
| r_id | r_e_id | r_u_id |
+-------+---------+---------+
| 1 | 2 | 1 |
| 2 | 2 | 3 |
| 3 | 5 | 4 |
| 4 | 2 | 4 |
| 5 | 1 | 1 |
+-------+---------+---------+
users
+-------+---------+----------+
| u_id | u_name | u_gender |
+-------+---------+----------+
| 1 | One | Male |
| 2 | Two | Male |
| 3 | Three | Female |
| 4 | Four | Male |
| 5 | Five | Female |
+-------+---------+----------+
I want to display an event page with the users that are subscribed to that event, like follows:
Event 2
Users:
- One
- Three
- Four
I have the following query with the problem that this one only displays the first user (so in this case Four), which makes sense because the mysql_fetch_assoc() is not in a while() loop.
$result = mysql_query("
SELECT events.e_title, reservations.*, users.u_name
FROM events
JOIN reservations
ON events.e_id = reservations.r_e_id
JOIN users
ON reservations.r_u_id = users.u_id
WHERE events.e_link = '".mysql_real_escape_string($_GET['link'])."'
");
$show = mysql_fetch_assoc($result);
What should i change in my query to make it work the way i want?
EDIT:
The solution from Teez works perfect, but wat if i want to attach more info, say for a link? My desired output is something like this:
Event 2
Users:
- User 1 Male
- User 3 Female
- User 4 Male
How am i going to achieve that? And eventually i even want to split the users by gender. So one list for females and one for males
SECOND EDIT:
I'm stunned with the result so far, but to complete it i want to sort the users by gender, like so:
Event 2
Users male:
- User 1 Male
- User 4 Male
Users female:
- User 3 Female
but how?
Best way will be first make a 2D array containing all events with respective users
Like below:
while( $show = mysql_fetch_assoc($result))
{
$events[$show['e_id']][]=$show['u_name'];
$uid[$show['e_id']][]=$show['u_id'];
}
Then loop arround above array for displaying :
foreach($events ad $key=>$users)
{
echo "Event ".$key."<br>";
echo "Users : <br>";
foreach($users as $ukey=>$name)
{
echo " -<a href='domain.com/user/".$uid[$key][$ukey]."'>".$name."</a>;
}
}
So with each call of mysql_fetch_assoc you want to have the event details and a list of usernames? In MySQL you can use GROUP_CONCAT for this purpose, although it is quite limited and error-prone. You should rather put mysql_fetch_assoc() in a loop to build an array of users. Anyway, here is the GROUP_CONCAT solution:
$result = mysql_query("
SELECT events.e_title, GROUP_CONCAT(users.u_name) e_reservation_users
FROM events
JOIN reservations ON events.e_id = reservations.r_e_id
JOIN users ON reservations.r_u_id = users.u_id
WHERE events.e_link = '".mysql_real_escape_string($_GET['link'])."'
GROUP BY 1
");
$show = mysql_fetch_assoc($result);
$show will then be
array('e_title' => '...', 'e_reservation_users' => '...,...,...').