mysql results sort by array - php

I think I don't understand how 'sort' works, so please don't judge me. I really searched all day long.
I have a movies table with actors column. A column it's named "actors". The actors are links separated by space " ". The order of the links it's very important.
I explode the links into an array which looks like [0]-> link0, [1]->link1, ...
I have the actors table where every actor also has it's movies links. I don't want to make 20 different sql searches so I made a variable with all the links I want, like this ( WHERE actor_link = link1 OR actor_link = link2 OR .. )
The problem is this. The search will probably find first the link7, and so my sorting it's gone. What can I do to keep that order from the movies table. I want to display the actors by popularity in the movie, not the order of my database.
Can you give me another method to search the actors without making 'x' sql searches and still keeping the order?
$actors[] = explode(" ", $row['actors_link']);
$x=0;
$actors2 = '';
while ($actors[0][$x]) {
$actors2 = $actors2 . "`link_imdb_actor` = " . "'".$actors[0][$x]."' OR ";
$x++;
}
$actors2 = substr($actors2, 0, -3);
$sql = "SELECT * FROM `actors` WHERE $actors2";
$sql_result = mysql_query($sql) or die(" ");
while ($row3 = mysql_fetch_array($sql_result)) {
echo $row3['link_imdb_actor'];
}
So, the movie Hotel Transylvania has Adam Sandler, Andy Samberg and Selena Gomez. My search shows Selena Gomez, Andy Samberg, Adam Sandler because this is the order from my database. How can I sort the sql results by the order of the actors array? Thank you!

To expand on Arjan's comment, if you want to be able to actually use the actor data (e.g. search with it) I would recommend at least two more tables. One called actors with the fields actorID, firstName, and lastName. The other table would be castings with the fields castingID, actorID, movieID, and castingOrder.
Each castingID will then link an actor to a movie - this would make for easy searches of every movie a particular actor has been in or every actor in a particular movie.
The castingOrder field can be used to maintain the order you want.

I need your existing code to really get the gist of what's going on.
I will make one suggestion in your query. Instead of saying WHERE actor_link = a OR actor_link = b OR actor_link = c do this instead:
WHERE actor_link IN (link1, link2, link3)

Related

how to get specific records

i'm making a simple site for movies and i wanna display related movies in the page..
the problem that my database contains American and Indian movies in movies table
i'm trying to find a way that when the visitor click on any american movie the related movies would appear only the american movies (there is a column called "movie_lang" in my table that labels the american movies as number 1 and the indian as number 2)
this's as far as i can get
$query=mysql_query("select * from movies order by id desc limit 4");
while($m=mysql_fetch_assoc($query)){
if($m['movie_lang']== '1'){
echo '<img src="uploads/poster/'.$m['thumbnail'].'" title="'.$m['name'].'">' ;}
else{
echo '<div class="hidden"></div>"';
}
}
not sure of my code. sorry...new to this...
If you wanna display only the american movies because the visitor click on it, you can show all the american movies using your query database.
$query = mysql_query("select * from movies where movie_lang = 1 order by id desc limit 4");
If you want the indian movies, just change the parameter in movie_lang to 2. This parameter can be for you a GET request.
Alright, I think I understand the issue, let me know if I missed it though: You want to list all types of movies, but if a user clicks a link for an american movie, you want to show him only american language movies on later pages. Here's my idea:
// When a page loads, it checks if the 'selected_lang' variable is set. If so, it creates a language filter
$previous_lang = isset($_GET['selected_lang'] && is_numeric($_GET['selected_lang'])) ? " where movie_lang = " . $_GET['selected_lang'] . " " : "";
// We assemble queries which will use a language filter if we have one, or all languages if not
$query=mysql_query("select * from movies $previous_lang order by id desc limit 4");
while($m=mysql_fetch_assoc($query)){
if($m['movie_lang']== '1'){
// We include a 'selected_lang' variable in our link, so that page now nows the language of the movie the user picked
echo '<img src="uploads/poster/'.$m['thumbnail'].'" title="'.$m['name'].'">' ;
} else {
echo '<div class="hidden"></div>"';
}
}
This code looks to see if a 'selected_lang' was set, and if so, uses it for subsequent SQL queries. You may have to chop bits here and there for different pages, and possibly re-arrange it if you want to write your own (sensible) where clauses.
Let me know if you need more help with this.

I want to get output result from second table based on first table rows output in json-php

I have knowledge of PHP but I am still learning Json. First of all I want to clear what I am looking for. I have two tables in mysql database, table1(users) and table2(business). Table "users" contains these rows(id, uid, business_name) and table "business" contains these rows(id, uid, category).
I have following code in PHP page:
if(isset($_GET['catName'])) {
$cat = $_GET['catName'];
$stmt = $pdo->prepare("SELECT id, uid, category FROM business WHERE category = ? ");
$stmt->execute(array($_GET['catName']));
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
I am able to get json output on my html page e.g.
101, 102, 103 and so on.
But I want to get business_name rows like ABC Business, XYZ Business, 123 Business and so on from second table "business" based on the output uid from first table. In brief, I want business_name output instead of uid output from second table.
Please help me. Thank you so much in advance.
You have an associative array, with the results from the query. It sounds like you want the business names, but you are not querying for them.
So the first step would be fix your broken query!
It's difficult to tell what you want from the query, but you're mixing the users table with the business table, so I'm guessing you really want business names based on users.
SELECT b.business_name FROM users u JOIN business b ON u.uid = b.uid WHERE category = ?
Then, you have to access your $arr variable correctly to get the business names
foreach ($arr as $bus_sql_result) {
echo $bus_sql_result['business_name']."\n";
}
This is not in JSON format, I'm not sure what JSON has to do with what you want, but if you really want it that way, you could try something like
$business_names = array();
foreach ($arr as $bus_sql_result) {
$business_names[] = $bus_sql_result['business_name'];
}
echo json_encode($business_names);
Thank you so much Chris and Jormundir. Joining the both tables really solved my problem. This is what I have done:
$stmt = $pdo->prepare("SELECT business.uid, users.business_name FROM business,users WHERE business.uid = users.uid AND business.category= ? ");
In html page I have put "business_name" array instead of "uid" and I have got result whatever I was looking for.
Thanks you so much all of you.

mySQL Search Statement with Multiple filters

I've been trying to figure this out for a few days now, but haven't been able to find a solution. Most likely due to the fact that I don't think I'm asking the right question.
Here is goes...
I am trying to create a search on my website of a list of attorneys.
Table 1
ID (primary)
Name
Category1 (fkey)
Category2 (fkey)
Category3 (fkey)
Category4 (fkey)
Category5 (fkey)
Location1 (fkey)
Location2 (fkey)
Location3 (fkey)
Location4 (fkey)
Location5 (fkey)
Table 2 - Locations
ID (primary)
Name
Table 3 - Categories
ID (primary)
Name
So Attorneys have multiple categories and multiple locations -> one to Many Relationship with both Table 2 and Table 3
First Question: Do I have Table 1 set up correctly? Do I need to have multiple location and category columns (ie location1, location2, location3, etc...) Or am I complicating this?
Next...
I want a checkbox style search on my site. A user can search by Location and/or by Category. And with checkbox they can choose multiple locations and/or categories. The checkbox values are the IDs of the locations and categories (not the names)
So three ways this can happen.
Search by locations ONLY
Search by categories ONLY
Search by categories within locations
I have two problems.
I can get scenarios 1 & 2 to work, but only if ONE checkbox is selected.
I have no idea how to even begin to get scenario 3 to work.
Here is what I have for scenario 1 & 2
$AttorneyLocation = $_POST['AttorneyLocation'];
for ($i="0"; $i<count($AttorneyLocation); $i++) {
if (!is_numeric($AttorneyLocation[$i])) {
$AttorneyLocation[$i]="";
}
if (empty($AttorneyLocation[$i])) {
unset($AttorneyLocation[$i]);
}
}
$AttorneyLocation = implode (" OR ", $AttorneyLocation);
$sqlCommand = "SELECT att_id, att_name, att_logo, att_addy, att_town, att_profile_url FROM attorneys WHERE att_location1='$AttorneyLocation' OR att_location2='$AttorneyLocation' OR att_location3='$AttorneyLocation' OR att_location4='$AttorneyLocation' OR att_location5='$AttorneyLocation'";
Again, this works but only when ONE checkbox is selected, it fails when two or more are selected. Basically it seems to only search the LAST checkbox that has been selected, ignoring the ones before it.
For scenario 3 - Again I'm just not sure where to start, how do I join together the category search within the location search?
If someone can point me in the right direction that would be great, thanks so much! This is my first try creating something like this!
Here is my form code if necessary - all created dynamically
<input type='checkbox' name='AttorneyCategory[]' value='$cat_id'> $category<br />
<input type='checkbox' name='AttorneyLocation[]' value='$loc_id'> $location<br />
As pointed out by #JonathanLeffler your structure for Table 1 is a perfect example of what not to do. Your Category* and Location* fields should be removed from Table 1 and replaced with two many-to-many tables - attorney_locations(attorney_id, location_id) and attorney_categories(attorney_id, category_id).
Start by amending your db structure and then we can address the other issues.
Next round -
<?php
foreach ($_POST['AttorneyLocation'] AS $key => $val) {
if (is_numeric($val)) {
$_POST['AttorneyLocation'][$key] = intval($val);
} else {
unset($_POST['AttorneyLocation'][$key]);
}
}
$AttorneyLocations = implode (',', $_POST['AttorneyLocation']);
foreach ($_POST['AttorneyCategory'] AS $key => $val) {
if (is_numeric($val)) {
$_POST['AttorneyCategory'][$key] = intval($val);
} else {
unset($_POST['AttorneyCategory'][$key]);
}
}
$AttorneyCategories = implode (',', $_POST['AttorneyCategory']);
$sqlCommand = 'SELECT DISTINCT att_id, att_name, att_logo, att_addy, att_town, att_profile_url FROM attorneys ';
if ($AttorneyLocations) {
$sqlCommand .= 'INNER JOIN attorney_locations ON attorneys.att_id = attorney_locations.attorney_id ';
}
if ($AttorneyCategories) {
$sqlCommand .= 'INNER JOIN attorney_categories ON attorneys.att_id = attorney_categories.attorney_id ';
}
$sqlCommand .= 'WHERE 1=1 ';
if ($AttorneyLocations) {
$sqlCommand .= "AND attorney_locations.location_id IN ($AttorneyLocations) ";
}
if ($AttorneyCategories) {
$sqlCommand .= "AND attorney_categories.category_id IN ($AttorneyCategories)";
}
You should print out what you get from your implode():
$AttorneyLocation = implode (" OR ", $AttorneyLocation);
It won't be valid SQL syntax, because you need it to read something like:
location = 'location1' OR location = 'location2' OR ...
So, you are not generating valid SQL, as you would surely see if you printed the SQL.
Your Table1 is a relational disaster. CategoryN or LocationN columns are SQL 'code smells'. It isn't clear what that table means; is it documenting 'AND' or 'OR' connections between the categories and locations, and is Category5 associated only with Location5 or is it also relevant to Location1? Without knowing what the data is supposed to mean, we can't reliably provide the correct design.
Given that each attorney may practice up to 5 categories of law, and may practice in up to 5 locations, then a better design for the tables is probably:
Attorney
ID (pkey)
Name
...other details...
AttorneyCategory
AttorneyID (fkey - references Attorney)
Category (fkey - references Category)
(AttorneyID, Category) (pkey)
AttorneyLocation
AttorneyID (fkey - references Attorney)
Location (fkey - references Location)
(AttorneyID, Category) (pkey)
This will actually be significantly easier to query, too, because you won't have to look up the same location name in each of five different columns, nor look up the same category in each of five different columns.
Well, since you are using PHP i just recommend you do an IF statement for each of the filters you want, maybe a few to make 2 or 3 filters work together. your database is set correctly, just create PHP if's with different queries and it should work.

Select unique text from an array

I am having a problem selecting the unique text from database.
This is for a movie database, Let's assume I have 2 movies in the database.
1st movie is in category: Drama, Romance, War
2nd movie is in category: Drama, Thriller
What I need, is to return an array wich will display me: Drama, Romance, War, Thriller.
My current query to mysql is the following:
$query = 'SELECT genres FROM imdb WHERE actors LIKE "%%'.$name.'%"';
In an while loop I use "foreach", like this:
foreach(explode(', ', $TMPL['genres']) as $v)
$TMPL['genre'] .= '<option value="'.urlencode($v).'">'.($v).'</option>';
This is returning me all the values, including the duplicated one, like this: Drama, Romance, WarDrama,Thriller
Any clue how to sort this out?
$query = 'SELECT DISTINCT genres FROM imdb WHERE actors LIKE "%%'.$name.'%"';
would do it
just use the array_unique function on that array of your with duplicate values!
$unique_values = array_unique($TMPL['genre']);
use DISTINCT
$query = 'SELECT DISTINCT genres FROM imdb WHERE actors LIKE "%%'.$name.'%"';
So you have a column with a delimited list of genres?
Loop through every row in your query and explode the genres, add every genre to a master array and then use array_unique()
If i understand you correctly you wont be able to do it (easily) with MySQL as you haven't normalised your database properly.

Items 'like' this one

I'm looking for some general advice on how to go about finding items 'like' the current one.
In my current example I have three tables like so (omitting unrelated data):
games
-game_id
genres
-genre_id
genres_data
-game_id
-genre_id
How can I go about finding games that have genres in common with the current one, from the ones that have all the same genres, descending to ones that only have one in common with it (limited of course to a few rows) with a given row from games?
What's the preferred method of finding like items?
Try this:
SELECT game_id, COUNT(genre_id) AS genres_in_common
FROM genres_data
WHERE
genre_id IN
(
SELECT genre_id
FROM genres_data
WHERE game_id = <game you're searching with>
)
AND
game_id != <game you're searching with>
GROUP BY game_id
ORDER BY genres_in_common DESC
;
The subquery grabs a list of all genre_ids associated with your game, and the main query uses that to search genres_data for any record that matches one of them. In other words, it searches for any game which is associated with any genre your "search game" is associated with.
Because a game can have multiple genres, this query would return the same game_id multiple times, and if you also reported the genre_id on these records they would each show a different genre_id. What we do to find the ones with the most in common is to group the results by each game_id, and we add the COUNT(genre_id) in the main SELECT to show how many different genre_ids there were for each game_id returned in that query.
From there, it's a simple matter of ordering that count of common genres in descending order, so that the games with the most genres in common will be listed first.
I also added a second criterion to the main query to exclude the game you're searching on from the results, otherwise that game would always have the most matches, for obvious reasons.
Hope that helps.
Surely the way to do this for just a single game is to first grab its genres and then loop over them to create a new query:
$query = "SELECT `genre_id` FROM `genres_data` WHERE `game_id` = 'your_game_id_here';"
$genre_id_result = mysql_result($query, $dbconn);
$num = mysql_num_rows($genre_id_result);
if ($num > 0) {
$query = "SELECT `game_id` FROM `games` WHERE ";
for ($i=0;$i<$num;$i++) {
$genre_id = mysql_result($genre_id_result, $i, "genre_id");
if ($WhereSQL == "") {
$WhereSQL = "genre_id = '$genre_id' "
} else {
$WhereSQL .= "AND genre_id = '$genre_id' "
}
}
$GamesInCommonResult = mysql_result($query . $WhereSQL, $dbconn);
}
You could set up a loop to do this for every game in the database and then collate your results. I can't think of how to do this in a single query at the moment.
I'm also a little unsure on your question as either you're looking for the genres that are the most popular (as games with these genres will likely be returned as having the most other games with the same genre in common) or you are looking individually for other game_ids of games in common with another game which might be more useful.

Categories