MYSQL: Showing the right records - html

I am trying to make a forum kind of thing for myself so I can learn from it. Now I need it to only show the 'topics' from a board with the right board_id as you can see on the first picture that are the boards and the second picture is the database with the topics so if I click on 'Nieuws & Events' board it only needs to show me the record with the topicnaam(topicname) = salespage.
I am only strugling to get this and I am not really sure what to do.
Ps. This is my first question so tell me if I am doing something wrong or if I am missing some important information.
Database with the main boards
Database with the forum topics
** The code to show the topics:**
<?php
$toppic = $app->get_topics();
foreach($toppic as $topic){
echo '<a href="https://tom.lbmedia.nl/reactie"> <div id="topic">';
echo '<div id="topicimg">';
if(file_exists('assets/images/profielfotos/'.$topic['klant_id'])) {
echo '<img class="img-circle" src="/assets/images/profielfotos/'.$topic['klant_id'].'/'.$topic['foto'].'" />';
} else {
echo '<i class="fa fa-fw fa-user img-circle"></i>';
}
echo '</div><div id="topictekst">';
echo '<b>'.$topic['topicnaam'].'</b>';
echo ' - ' . $topic['voornaam'] . " " . $topic['achternaam'] ;
echo '<span style="float:right; margin-top:15px; margin-left:5px;">reacties</span> <span style="float:right; color:grey; margin-top:15px"class="fa fa-comment"></span>';
echo '<hr><span class="badge bg-red">' . $board['topic'] . '</span>';
echo '</div></div></a>';
}
?>
The functions I am using:
public function get_boards(){
$getBoards = $this->database->query("SELECT boards.*, ledenpagina.ledenpagina_id FROM boards
LEFT JOIN ledenpagina ON ledenpagina.ledenpagina_id = boards.ledenpagina_id
ORDER BY id DESC");
// $this->database->bind(":ledenpagina_id", $_SESSION['ledenpagina_id']);
$boards = $this->database->resultset();
return $boards;
}
public function get_topics(){
$getTopic = $this->database->query("
SELECT topics.*, klanten.foto, klanten.voornaam, klanten.achternaam FROM topics
LEFT JOIN klanten ON topics.klant_id=klanten.id
ORDER BY id ASC");
// $this->database->bind(":ledenpagina_id", $_SESSION['ledenpagina_id']);
$topics = $this->database->resultset();
return $topics;
}

Your code is:
If you have in input the board id:
SELECT t.* FROM topics t
JOIN boards b
ON t.borad_id = b.id
WHERE b.id = 2
or
SELECT t.* FROM topics t
WHERE t.borad_id = 2
If you have in input board description:
SELECT t.* FROM topics t
JOIN boards b
ON t.borad_id = b.id
WHERE b.description = 'Nieuws & Events'

Use Join
Here is an example:
SELECT Boards.id, Boards.topic, Topics.board_id, Topics.topicnaam
FROM Boards
INNER JOIN Topics
ON Boards.id=Topics.board_id
WHERE Boards.id = 2;

Related

Displaying Foreign Key data in MySQL

I have a BusinessID in both my staff and business table and I'm wanting to display the staff members for everyone in a particular business. The query below gives me this error.
ERROR: Could not able to execute SELECT * FROM business b inner join BusinessID b ON b.BusinessID = s.BusinessID WHERE b.BusinessID = 1. Not unique table/alias: 'b'
This is my foreign key file
<html>
<body>
<?php
include_once("connect.php");
$BusinessID = $_GET['BusinessID'];
$sql= "SELECT *
FROM business b
inner join BusinessID b
ON b.BusinessID = s.BusinessID
WHERE b.BusinessID = $BusinessID";
if($result = $conn->query($sql)){
if($result->num_rows > 0){
echo "<table>";
echo "<tr>";
echo "<th>Name</th>";
echo "<th>BusinessID<th>";
echo "</tr>";
while($row = $result->fetch_array()){
echo "<tr>";
echo "<td>" . $row['Name'] . "</td>";
echo "<td>" . $row['BusinessID'] . "</td>";
echo "</tr>";
}
echo "</table>";
// Free result set
$result->free();
} else{
echo "No records matching your query were found.";
}
} else{
echo "ERROR: Could not able to execute $sql. " . $conn->error;
}
// Close connection
$conn->close();
?>
</body>
</html>
Below is the fix
$sql= "SELECT *
FROM staff
WHERE BusinessID = $BusinessID";
You need to use a join statement
Select *
From staff as S
Join business as B
on s.businessID=b.businessID
--Where clause <--- If you want to filter by anything.
You say you "have a BusinessID". If it were in $BusinessID, the form of query you want seems to be:
query select * from staff where s.BusinessID = $BusinessID
However be warned of SQL code injection as addressed at How can I prevent SQL injection in PHP? (See also the coincidental meta post from today Should the answer be the simplest ever possible, even at the expense of quality/security?) The correct way to deal with this in a PHP context is to query via prepared statements.

Get members from each team via SQL JOINS

I have 3 tables, members, teams & team_members.
team_members houses the ids from both the members & teams and stores them per row.
The schema of theteam_members table:
teams table:
What I'd like to be able to do is create a join where i can output the team_name from the teams table and then underneth show the members_firstname associated with that that team. So example:
Team 1
joe bloggs
jon doe
Team 2
charlie chaplin
hulk hogan
My php code looks like this:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$sql = "SELECT t.team_name, group_concat(m.firstName)
FROM members AS m
JOIN team_members AS tm
ON tm.member_id = m.member_id
JOIN teams as t
on t.team_id = tm.team_id
GROUP BY t.teamname";
$result = $conn->query($sql);
if($result->num_rows > 0){
while($row = $result->fetch_assoc()){
echo $row["member_id"] . '<br>';
echo $row["team_id"] . '<br><br>';
}
}
?>
Now I get:
Notice: Trying to get property of non-object in -- on line 30 which is:
if($result->num_rows > 0){
You should use two joins to piece together the three tables.
SELECT t.team_name as team_name, group_concat(m.firstName) as team_members
FROM members AS m
JOIN team_members AS tm
ON tm.member_id = m.member_id
JOIN teams as t
on t.team_id = tm.team_id
GROUP BY t.team_name
You then should check the status of your query before trying to work with it.
if(!$result = $conn->query($sql)) {
die(printf("Errormessage: %s\n", $conn->error));
}
Then loop through the results, and split the grouped values by the comma.
while($row = $result->fetch_assoc()){
echo $row["team_name"] . '<br>';
$names = explode(',', $row['team_members']);
foreach($names as $name) {
echo $name . '<br>';
}
echo '<br>';
}
You also could use <br> as the separator in the group_concat. You can read more about that function here, http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat. If you did that you can get rid of the foreach and explode because the $row['team_members'] would be built with a linebreak for each member.
The easy way to do this in PHP is width two nested loops in first you go trought the team table and print it in the second you print all the playes width theat team id...
Something like:
do{
echo $row_team;
do{
echo $row_playa;
}while($row_plya = mysql_fetch_assoc($playas)); // whear pleya.team_id = $row_team.id
}while($row_team = mysql_fetch_assoc($teams));

Why is this wrong in joomla?

using joomla with k2 I am trying to call from my database the category that is assigned with my item title and I use this code.In order to achieve this. But something is wrong. I do get the title but I am not getting the category name. Below is the code that I am using to get it:
?php
$url= $_SERVER['REQUEST_URI'];
$data = parse_url($url);
$number = basename($data['path'], '.html');
$needle="-";
$number1=substr($number, 0, strpos($number, $needle));
?>
<?php
$db =& JFactory::getDBO();
$db->setQuery('SELECT title FROM #__k2_items WHERE id="'.$number1.'"');
$databaseTitle = $db->loadResult();
$db->setQuery('SELECT catid FROM #__k2_items WHERE id="'.$number1.'"');
$databaseCatid= $db->loadResult();
$db->setQuery('SELECT #__k2_categories.name FROM #__k2_categories INNER JOIN #__k2_items ON #__k2_categories.id = #__k2_items.catid WHERE #__k2_items.catid ="$databaseCatid" LIMIT 1');
$databaseNamecat= $db->loadResult();
?>
<h2>Submit a Charter Request for <?php echo $databaseTitle." from port ".$databaseNamecat; ?></h2>
because you are enclosing a variable between double quotes.
try this
$db->setQuery("SELECT #__k2_categories.name FROM #__k2_categories INNER JOIN #__k2_items ON #__k2_categories.id = #__k2_items.catid WHERE #__k2_items.catid ='".$databaseCatid."' LIMIT 1 ");

can this phpbb query be optimized?

Here's some code adapted from phpBB. Near as I can tell it's trying to delete all topics wherein the only poster is the target user.
(note that for testing purposes I changed the final query from a DELETE to a SELECT)
<?php
$user_id = 66275;
mysql_connect('localhost', 'username', 'password');
mysql_select_db('db_name');
$start = microtime(true);
$total = 0;
define('POSTS_TABLE', 'phpbb_posts');
define('TOPICS_TABLE', 'phpbb_topics');
$sql = 'SELECT topic_id, COUNT(post_id) AS total_posts
FROM ' . POSTS_TABLE . "
WHERE poster_id = $user_id
GROUP BY topic_id";
$result = mysql_query($sql);
$topic_id_ary = array();
while ($row = mysql_fetch_assoc($result))
{
$topic_id_ary[$row['topic_id']] = $row['total_posts'];
}
mysql_free_result($result);
if (sizeof($topic_id_ary))
{
$sql = 'SELECT topic_id, topic_replies, topic_replies_real
FROM ' . TOPICS_TABLE . '
WHERE ' . sql_in_set('topic_id', array_keys($topic_id_ary));
$result = mysql_query($sql);
$del_topic_ary = array();
while ($row = mysql_fetch_assoc($result))
{
if (max($row['topic_replies'], $row['topic_replies_real']) + 1 == $topic_id_ary[$row['topic_id']])
{
$del_topic_ary[] = $row['topic_id'];
}
}
mysql_free_result($result);
if (sizeof($del_topic_ary))
{
$sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . '
WHERE ' . sql_in_set('topic_id', $del_topic_ary);
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result))
{
$total++;
echo $row[topic_id] . "\r\n";
}
}
}
function sql_in_set($field, $array, $negate = false, $allow_empty_set = false)
{
if (!sizeof($array))
{
if (!$allow_empty_set)
{
// Print the backtrace to help identifying the location of the problematic code
$this->sql_error('No values specified for SQL IN comparison');
}
else
{
// NOT IN () actually means everything so use a tautology
if ($negate)
{
return '1=1';
}
// IN () actually means nothing so use a contradiction
else
{
return '1=0';
}
}
}
if (!is_array($array))
{
$array = array($array);
}
if (sizeof($array) == 1)
{
#reset($array);
$var = current($array);
return $field . ($negate ? ' <> ' : ' = ') . $var;
}
else
{
return $field . ($negate ? ' NOT IN ' : ' IN ') . '(' . implode(', ', $array) . ')';
}
}
$elapsed = microtime(true) - $start;
echo "\r\ntook $elapsed seconds";
echo "\r\ngot $total rows back";
?>
This does three queries. First gets all the topics the target user has posted in and the number of times they've posted in each topic. The second gets how many replies each topic in the first query actually has. Then there's some PHP code to see which topics have had all their posts made by the target user. After that the code (prior to my changes) DELETEs all those topics.
Overall it seems to me that this could be written better by doing something like this:
SELECT t.topic_id
FROM phpbb_topics AS t
JOIN phpbb_posts AS p1
ON p1.topic_id = t.topic_id
AND p1.poster_id = $poster_id
LEFT JOIN phpbb_posts AS p2
ON p2.topic_id = t.topic_id
AND p2.poster_id <> $poster_id
WHERE p2.poster_id IS NULL;
Or maybe this:
SELECT t.topic_id
FROM phpbb_topics AS t
JOIN phpbb_posts AS p1
ON p1.topic_id = t.topic_id
AND p1.poster_id = $poster_id
AND t.topic_poster = $poster_id
AND t.topic_last_poster_id = $poster_id
LEFT JOIN phpbb_posts AS p2
ON p2.topic_id = t.topic_id
AND p2.poster_id <> $poster_id
WHERE p2.poster_id IS NULL
Testing this is actually quite difficult thanks to MySQLs caching but... from what testing I have been able to do it seems like the way phpBB is currently doing it is in fact faster. Which is surprising to me.
Any ideas?
It looks to me like you are on the right track. Try adding indexes to all the columns you are using in the joins as this can often drastically increase the speed of joins.

Using DISTINCT to filter duplicates?

I have the following query, and would like to list only the first match.
$first = $_GET['category'];
$first = $first[0] . "%";
$query = mysql_query("SELECT * FROM lyrics WHERE authorclean LIKE '".$first."'") or die(mysql_error());
(?category=b)
So DISTINCT could do this right? This is what I tried, but did not work:
$query = mysql_query("SELECT DISTINCT authorclean FROM lyrics WHERE authorclean LIKE '".$first."'") or die(mysql_error());
EDIT: Here is the full code:
function getCategory() {
$first = $_GET['category'];
$first = $first[0] . "%";
$query = mysql_query("SELECT DISTINCT authorclean FROM lyrics WHERE authorclean LIKE 'B%'") or die(mysql_error());
//$query = mysql_query("SELECT * FROM lyrics WHERE authorclean LIKE '".$first."'") or die(mysql_error());
if(mysql_num_rows($query) == 0) {
echo "Geen resultaten gevonden.";
} else {
while ($row = mysql_fetch_assoc($query)) { ?>
<p><?= $row['author']; ?></p>
<?php }
}
}
(B% is just for testing)
If I run this following query in the database directly I get two results. If I run with the code above I just get an empty page (except for the html thats already there).
SELECT DISTINCT authorclean FROM lyrics WHERE authorclean LIKE 'B%'
You should use LIMIT 1 to list only the first match.
If you have a a table "tbl_lyrics" with fields: author lyrics year and is filled for example as follows:
author_A lyrics_A year_A
author_A lyrics_A1 year_A1
author_A1 lyrics_A2 year_A
author_B lyrics_B1 year_B1
if you do
select distinct(author) from tbl_lyrics where author like '%author_A%'
you are going to get: author_A and author_A1. NOT the first one that matches.
If you want the first one that matches you can do:
select author from (select distinct(author) as author from tbl_lyrics where author like '%author_A%') where rownum <2;
this will return author_A only.
Limit is used with MySql but would not work with oracle databases