• 0

[PHP] You may also like... MySQL Query


Question

I have a SQL table called users_fav_bands. I want to create a way so that it will show users similar bands to what bands page they are.

Here is the table..

+------------------------------+---------------------------+
|	users_fav_bands_user_id   |	users_fav_bands_band   |
|						  2   |					   4   |
|						  3   |					   4   |
|						  3   |					   3   |
|						  1   |					   2   |
|						  3   |					   2   |
|						  2   |					   2   |
+------------------------------+---------------------------+

If I am looking at band 2, I want it to display bands that other people like. So it will show that 2 people (people 2 and 3) enjoy band 4 and one person (3) enjoys band 3. Also, if you could show me how to limit it, so it would only show the top 5 bands that people enjoy.

Thanks :D

Link to comment
https://www.neowin.net/forum/topic/497436-php-you-may-also-like-mysql-query/
Share on other sites

18 answers to this question

Recommended Posts

  • 0

Indead, confusing. Ill give it ago from what your telling me.

<?
//Do the appropriate mysql connections
$band = 2;
$result = mysql_query("SELECT COUNT(*) FROM `users_fav_bands` WHERE band = '$band'"); 
$num_rows = mysql_fetch_row($result);
$num_rows = $num_rows[0];
echo $num_rows;
?>

That would echo 2....right? Did you want to list the top bands then?

  • 0

do you want the 'you may also like list' to be based on the most common other bands listed in other people's lists who also have the same band(s) as the current user, or do you want to limit it to 'friends' lists as you seemed to suggest in your third post?

breaking down the problem:

- get all the bands listed for the current user

- for each band, search for all entries with that band and grab the users id unless its the current users id or youve already got the id

- for each id you grabbed, get all the bands the user likes excluding ones the original user already has in their list, counting the number of timeseach band occured

- print out the top five bands other people had listed

would that be what you want to do? if so then we can attempt to code it!

did you want to limit it to only searching 'friends' lists not just anyones? would you want to limit searches to people who have say two bands the same as the current user and ignore other people with only one band the same?

  • 0
  theblazingangel said:
the 'you may also like list' to be based on the most common other bands listed in other people's lists who also have the same band(s) as the current user

That's what I want - you can see what I was trying to do here - https://www.neowin.net/forum/index.php?showtopic=493940

  • 0

sorry, i forgot about you, im pretty busy

try the following code, you just need to call the function passing in the id of the current user e.g. get_recommendations('2');

would you like me to add to it so only people with say 2 or more same bands as you are used to get recommendations from rather than just 1 or more.

function get_recomendations($user_id)
{
	// get current users five favourite bands (assumes only five bands listed)
	$query = "SELECT users_fav_bands_band FROM users_fav_bands WHERE users_fav_bands_user_id='$user_id' LIMIT 5"
	$result = mysql_query($query);
	if ($result == false)
	{
		echo "error occured";
		return false;
	}

	// extract id's of users five favourite bands from results and store them as a string in query format
	$count = 0;
	while ($row = mysql_fetch_assoc($result))
	{
		extract($row);

		if ($count = 0)
		{
			$band_ids = "users_fav_bands_band=" . $users_fav_bands_band;

		} else {

			$band_ids .= " OR users_fav_bands_band=" . $users_fav_bands_band;
		}

		$count++;
	}

	// get id's of users who have one or more of the same bands
	// - this uses the string created above, and excludes the current user from results
	$query = "SELECT DISTINCT users_fav_bands_user_id FROM users_fav_bands WHERE users_fav_bands_user_id<>'$user_id' AND ($band_ids)"
	$result = mysql_query($query);
	if ($result == false)
	{
		echo "error occured";
		return false;
	}

	// extract id's of returned users from results and store them as a string in query format
	$count = 0;
	while ($row = mysql_fetch_assoc($result))
	{
		extract($row);

		if ($count = 0)
		{
			$other_users_ids = "users_fav_bands_user_id=" . $users_fav_bands_band;

		} else {

			$other_users_ids .= " OR users_fav_bands_user_id=" . $users_fav_bands_band;
		}

		$count++;
	}

	// alter band id string so it can be used to exclude the songs from results
	//  - swaps '=' with '<>' in the string to exclude data
	$temp = explode('=',$band_ids);
	$band_ids = implode('<>',$temp);

	// get id's of songs the other users have which you havent got
	//  - this uses the string of user id's created above limiting results to users who have some of the sam ebands as you
	//  - this also uses the string of band id's created above, this time to exclude songs you already have from the results
	//  - it also creates a temporary table from which results can be retrieved with further queries, rather than returning data
	$query = "CREATE VIEW other_songs AS SELECT users_fav_bands_band FROM users_fav_bands WHERE ($other_users_ids) AND ($band_ids)"
	$result = mysql_query($query);
	if ($result == false)
	{
		echo "error occured";
		return false;
	}

	// get list of bands from temporary table created above
	$query = "SELECT DISTINCT users_fav_bands_band FROM [other_songs]"
	$result = mysql_query($query);
	if ($result == false)
	{
		echo "error occured";
		return false;
	}

	// for each band count the number of times its listed in the temporary table that was created above
	{
		$other_bands = array();
		$count = 1;

		// fetch each unique band id
		while ($row = mysql_fetch_assoc($result))
		{
			extract($row);

			// count how many times it occurs
			$query = "SELECT count(users_fav_bands_band) FROM [other_songs] WHERE users_fav_bands_band IN ($users_fav_bands_band)"
			$result = mysql_query($query);
			if ($result == false)
			{
				echo "error occured";
				return false;

			} else {

				// store the bands id and the number oftimes it occurs in array
				$other_bands[$count][id] = $users_fav_bands_band;
				$other_bands[$count][count] = $result;
			}

			$count++;
		}
	}

	// get recommended bands, starting with the one that occured the most times
	{
		// set max number of recommended entries to get
		$limit = 5;

		// if the number of bands is less than the limit, reduce the limit
		if (count($other_bands) < $limit) { $limit = count($other_bands); }

		// do searches
		for ($i=1; $i<=$limit; $i++)
		{
			$max = 0; // store current largest number of recurrances
			$maxArrID = 0; // store id of array entry for highest recurring band

			// search array for the band that reccurs the most
			//  - this takes into account entries that occur the same number of times and will print them out one at at time starting at the first occuring one!
			for ($j=0; $j<count($other_bands); $j++)
			{
				// if number of occurances for current array entry larger than number stored, set this entry as the largest
				if ($other_bands[$j][count] > $max)
				{
					$max = $other_bands[$j][count]; //store number of largest occurances found
					$maxArrID = $j; //store id of the array entry that had it
				}

				// print recommendation to screen
				echo "band id #" . $j . ": " . $other_bands[$maxArrID][id] . "<br />\n";

				// remove entry from array so the next highest recurrer can be found
				unset($other_bands[$maxArrID][id]);
				unset($other_bands[$maxArrID][count]);
			}
		}
	}

	return true;
}

  • 0

Hey, thanks for that script - but sadly, it doesn't work. I tried playing with it a bit, but it keeps getting stuck on

$band_ids .= " OR users_fav_bands_band=" . $users_fav_bands_band;

As I get the error

Notice: Undefined variable: band_ids in /Library/WebServer/Documents/test.php on line 31
error occured

Any ideas?

  • 0

ah, spotted the bug, in the first WHILE statement, swap

if ($count = 0)

with

if ($count == 0)

ive attached the fixed code in a text file if you need it ;)

get_recommendations_php.txtFetching info...

edit: i noticed i made a spelling mistake in the functions name, ive changed it and re-uploaded the attached text file

  • 0

I fixed both of the if ($count = 0)'s to reflect that change.

Now I get an error after the SQL command

CREATE VIEW other_songs AS SELECT users_fav_bands_band FROM users_fav_bands WHERE ($other_users_ids) AND ($band_ids)

I'm running MySQL 5.0.19. Any more ideas? :D

  • 0

ive setup a test database so i can run the code and check it works. ive solved the problem above but found no results are being printed out so im doing some tests to find the problem. at the moment ive found that the second query is for some reason returning the wrong results and im trying to find out why. i'll post the code when ive fixed it.

  • 0

okay, serves me right trying to write so much code without testing it, all together i've found several missing semi-colons, incorrect use of views, two instances of '=' instead of '==', an incorrectly initiated loop, and even an infinate loop.

anyway, heres the fixed code and hopefully it should work fine now :D

get_recommendations_php.txtFetching info...

note, i should have said before that this code requires MySQL v5.0.1 or greater. and btw v5.0.24a is the latest stable release (i noticed you said you have v5.0.19).

  • 0

well, if you passed in the user id '1', according to the example table you posted in the first post, it would find bandID '2' to be the only band listed for userID '1'. it would then look for other people with bandID '2' listed and would find userID's '2' and '3'. it would then look at what other band's those users like which would be '3' and '4'. because two people like bandID '4', bandID '4' is the first recommended result. bandID '3' is then the second recommendation.

the numbers printed as recommendations are the ID's of the recommended bands, i can get it to print the names of the bands if i know the exact layout of the table that stores them (+table name)

in the results you posted above, were four lines really printed out, because if so thats another bug i need to fix.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Ashes of the Singularity II announced promising even larger battles, new faction, and more by Pulasthi Ariyasinghe A sequel for the 2016-released Ashes of the Singularity has officially been confirmed, and the original developer and publisher duo, Oxide Games and Stardock Entertainment, are back for this release too. Check out the debut trailer above. Ashes of the Singularity II is under development with a significantly expanded team compared to the original, according to today's announcement. It will be adding in a range of fresh units and gameplay systems for real-time strategy fans to dive into. More options for strategic gameplay, more intricate base building, and better enemy AI are listed as features for the new game as well. "Ten years ago, we set a new, literal benchmark for RTS games with massive battles and groundbreaking technology," said Brad Wardell, CEO of Stardock Entertainment. "With Ashes of the Singularity II, we’re raising the bar even higher, delivering strategic gameplay depth that RTS fans have always dreamed of.” The storyline of Ashes of the Singularity II will take place in 2031, with a complete single-player campaign, as well as cooperative and competitive multiplayer modes, being confirmed as features today. Moreover, a third faction is joining the fray this time, with Humans joining the fight alongside the original games' Post-Human Coalition and the Substrate. "Obviously, in the first game, the number one request was to have a human faction," adds Wardell. “Back then, we just couldn’t support having thousands of organic, walking, squishy people in the world and thus had to design in favor of machines. We’re really excited to bring the humans into the war and watch how they fare against the massive mechanical armies of the Substrate and PHC.” Ashes of the Singularity II is targeting a broad 2026 release window, with the team hoping to launch the title as the original celebrates its 10th anniversary. Its Steam store page is already up for wishlisting over here. Disclaimer: Neowin's relationship to Stardock
    • How exactly is a FREE image generation model a... Ponzi scheme?!?! I don't love all of these Gen-AI things flooding the market but there's nothing "ponzi" about it.
    • I can't decide if this is tacky or a really fun move for more casual players like myself to enjoy. I'll be curious to see how we are to fly to fictional land masses on a real globe.
  • Recent Achievements

    • One Month Later
      SamZrize earned a badge
      One Month Later
    • Week One Done
      SamZrize earned a badge
      Week One Done
    • One Year In
      SamZrize earned a badge
      One Year In
    • One Year In
      barracuda earned a badge
      One Year In
    • One Month Later
      barracuda earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      724
    2. 2
      +FloatingFatMan
      189
    3. 3
      ATLien_0
      180
    4. 4
      Xenon
      113
    5. 5
      neufuse
      109
  • Tell a friend

    Love Neowin? Tell a friend!