mysql join one to many with images - mysql

I have two tables...
project table
+----+--------+
| id | client |
+----+--------+
| 1 | James |
| 2 | John |
+----+--------+
images table
+----+-----------+-------------------+
| id | projectId | imagePath |
+----+-----------+-------------------+
| 1 | 1 | images/image1.jpg |
| 2 | 1 | images/image2.jpg |
| 3 | 2 | images/image3.jpg |
| 4 | 2 | images/image4.jpg |
| 5 | 2 | images/image5.jpg |
+----+-----------+-------------------+
As you can see, one project has many images. I want to display that
this way...
James
images/img1.jpg
images/img2.jpg
John
images/img3.jpg
images/img4.jpg
images/img5.jpg
This post gave me what I want https://stackoverflow.com/a/2451065/1214535
But when I echo like so
<img src='".$row['imagePath']."/>
the results in image tag I get this
<img src="images/img3.jpg,images/img4.jpg,images/img5.jpg">
instead of
<img src="images/img3.jpg"/>
<img src="images/img4.jpg"/>
<img src="images/img5.jpg"/>
How can I change the query so that I can display the images properly/separately
this is the query I am using
$sql="SELECT images.projectId,project.client,
GROUP_CONCAT(images.imagePath SEPARATOR ', ')
AS 'imagePath'
from project left JOIN images on project.id=images.projectId
GROUP BY project.id ASC";
thank you guys...

You could try using foreach to loop through different values.
Syntax:
foreach (array_expression as $value)
statement
First insert all the values you get in an array like this:
$imgArray = explode(',',$row['imagePath']);
Then loop through this array as:
foreach ($imgArray as $img)
{
echo "<img src='$img'" />";
}

you have to break the string like below
$imgArray = explode(',',$row['imagePath']);
//then do
foreach($imgArray as $im)
{
if( is_readable($im) ) {
echo "<img src='$im' title='Image' />";
}
}

I believe that EXPLODE is the answer.Look at PHP explode - running loop through each array item Stack overflow question. I believe that it will answer to your question.
Also, I think (another approach) if you change ur query to
SELECT tp.CLIENT,ti.IMAGEPATH
FROM tblProject tp
JOIN tblImage ti ON tp.Id = ti.ProjectId
then a simple loop will be easy to get you through.

Because you are using GROUP_CONCAT which is returning all non-null values as string.
You can use below query:
$sql="SELECT images.projectId,project.client,images.imagePath SEPARATOR
AS 'imagePath'
from project left JOIN images on project.id=images.projectId
GROUP BY project.id ASC";
And loop through result.

Related

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++;
}

Missing an option to use SQL's HAVING clause in F3

Is there a way to use MySQL's HAVING clause with any of Fat Free Framework's SQL Mapper object's methods? Let's assume I have the following DB table:
+----+-------+--------+
| id | score | weight |
+----+-------+--------+
| 2 | 1 | 1 |
| 2 | 2 | 3 |
| 2 | 3 | 1 |
| 2 | 2 | 2 |
| 3 | 1 | 4 |
| 3 | 3 | 1 |
| 3 | 4 | 3 |
+----+-------+--------+
Now I would like to run a following query:
SELECT id, SUM(score*weight)/SUM(weight) AS weighted_score GROUP BY id HAVING weighted_score>2
Truth to be told I would actually like to count the number of these records, but a count method doesn't support $options.
I can run the query without a HAVING clause and then loop through them to check weighted_score against the value, but with a growing number of records will make it more and more resource consuming. Is there any built-in solution to solve this problem?
EDIT 1:
The way I know how to do it if there is no support for the HAVING clause (based on manual):
$databaseObject = new DB\SQL(...);
$dataMapper = new \DB\SQL\Mapper($databaseObject, "tableName");
$dataMapper->weightedScore = "SUM(weight*score)/SUM(weight)";
$usersInfo = $dataMapper->find([],["group"=>"id"]);
$place = 1;
foreach ( $usersInfo as $userInfo ) {
if ( $usersScores->weightedScore > 2) $place++;
}
If I were able to use HAVING clause then the foreach loop would not be needed and the number of items loaded by a query would be reduced:
$databaseObject = new DB\SQL(...);
$dataMapper = new \DB\SQL\Mapper($databaseObject, "tableName");
$dataMapper->weightedScore = "SUM(weight*score)/SUM(weight)";
$usersInfo = $dataMapper->find([],["group"=>"id", "having"=>"weighted_score<2"]); // rough idea
$place = count($usersInfo);
And if count method supported $options it would be even simpler and it would save memory used by the app as no records would be loaded:
$databaseObject = new DB\SQL(...);
$dataMapper = new \DB\SQL\Mapper($databaseObject, "tableName");
$dataMapper->weightedScore = "SUM(weight*score)/SUM(weight)";
$place = $dataMapper->count([],["group"=>"id", "having"=>"weighted_score<2"]); // rough idea
Use Sub Query.
select count (0) from (SELECT id, SUM(score*weight)/SUM(weight) AS weighted_score GROUP BY id) where weighted_score>2;
Hope it will help.
As far as I know, you can put the HAVING clause into the group option:
$usersInfo = $dataMapper->find([],["group"=>"id HAVING weighted_score<2"]);
Another way could be to create a VIEW in mysql and filter the records on a virtual fields in that view.

How to merge two tables in a mysql query

First of sorry I know mysql is not recommended any more but in this case I have no control and have to use it.
Now onto the question.
I have two tables
Games and videos
Inside games I have
| id | gameID | GameTitle |
| 1 | 1 | Halo ODST |
| 2 | 2 | Disgaea 4 |
Inside videos I have
| id | game | videoTitle | image |
| 1 | 1 | Title 1 | PATH |
| 2 | 1 | Title 2 | PATH |
| 3 | 2 | Title 3 | PATH |
| 4 | 1 | Title 4 | PATH |
I need to basically do the following
Select x,y,z from video where videos.game = games.gameID
which will basically read
select id, videoTitle, image from videos where video.game = 1
(or some other numeric value)
I’m aware I have to use a join however nothing I have tried appears to be working and yeah I’m getting nowhere with this.
The closest I am is the below query which says it works but is returning an empty result set so clearly its wrong somewhere.
SELECT * FROM `games` INNER JOIN `videos` on `game` WHERE `game` = 1
If its any help I'm using phpmyadmins sql query tool rather than actual code at this stage as i just want to get it working before coding it.
Any help is greatly appreciated.
Thanks.
SELECT *
FROM `games` g
INNER JOIN
`videos` v
ON v.game = g.gameId
WHERE g.gameId = 1
you can use view to merge table and can perform operations on that..
create view view_name as
select Games.id,gameID, GameTitle,videos.id, game, videoTitle, image
from Games,videos
where videos.game = games.gameID
where section will contain ids or anything you want to match

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.

SQL concatenate rows query

Say we have a table
table posts
+---------+-----------+--------------------------------+
| postId | title | status | bodyText |
+---------+-----------+--------------------------------+
| 1 | Hello! | deleted | A deleted post! |
| 2 | Hello 2! | deleted | Another one! |
| 3 | New 1 | new | A new one! |
| 4 | New 2 | new | A new one again! |
Can we, in SQL, retrieve a concatenation of a field across rows, by issuing a single query, not having to do the join up in a loop in our back-end code?
Something like
select title from posts group by status ;
Should give a result like
+---------+--------------------+
| deleted | Hello!, Hello 2! |
| new | New 1, New 2 |
If you use MySQL then you can use GROUP_CONCAT:
SELECT status, GROUP_CONCAT(title)
FROM posts
GROUP BY status
In MySQL:
SELECT status, GROUP_CONCAT(title SEPARATOR ', ')
FROM posts
GROUP BY
status
In PostgreSQL:
SELECT status,
ARRAY_TO_STRING(
ARRAY(
SELECT title
FROM posts pi
WHERE pi.status = po.status
))
FROM posts po
GROUP BY
status
You didn't indicate a particular SQL engine.
In Firebird (from 2.1) you can use the LIST() function. Take a look at: link text
It's an aggregate function to do exactly what you need.
I guess it exists in other engines (LIST in Sybase SQL Anywhere, GROUP_CONCAT in MySQL)