MySQL GROUP by or using PHP? - php

I have an issue that seems to be quiet easy but I just would like to ask how you would solve it:
In a MySQL-table there is the following structure:
provider artist
a 1
a 2
a 3
b 4
Now it is necessary to echo a list in HTML like:
provider a
1
2
3
provider b
4
I stuck at the point where I would like to group the results and echo them out with for-each and while loop.
The main idea is quiet simple like:
<?php $query = mysqli->query("SELECT * FROM `table` GROUP by provider");
foreach GROUP {?>
echo some styling HTML-code for each group of headline;
<?php while ($data= $query->fetch_assoc()){?>
echo some styling HTML-code for each list-item;
<?php};?>
Thanks in advance.
UPDATE:
Thanks for answering.
The solution fro RiggsFolly seems to work fine. There is just a small problem with the HTML. There is a surrounding div-tag that wont be closed when adding the HTML code in that line:
echo 'provider '. $data->provider;
The problem is that the while loop needs to be in the div. The closing div-tag is missing for every
if ( $current_provider != $data->provider ) {
Here is the original HTML-code:
<?php
$service = $db->query("SELECT * FROM `system` ORDER BY provider, artist");
$current_provider = NULL;
while ($data = $service->fetch_object()) {
if ( $current_provider != $data->provider ) {// new provider?>
<div class="service">
<p class="lower">
<?php echo $data->provider;?>
</p>
<?php
$current_provider = $data->provider;
}?>
<a href='?artist=<?php echo $data->artist;?>'><?php echo "/".$data->artist;?</a><br/>
<?php };?>
</div><!--service -->
The list-items will be shown nicely. But when looking into the Source code you can see that the closing div-tag is missing. Thanks
Kind regards.

It would seem simpler to not use a GROUP BY especially as it will not provide you with the data that you want. So instead just select them all and sort them by provider and maybe artist as a sub sort like so
<?php
$result = $mysqli->query("SELECT * FROM `table` ORDER BY provider, artist");
$current_provider = NULL;
while ($data = $result->fetch_object()){
if ( $current_provider != $data->provider ) {
// new provider
echo 'provider '. $data->provider;
$current_provider = $data->provider;
}
echo $data->artist;
}
?>
AFTER UPDATE:
<?php
$service = $db->query("SELECT * FROM `system` ORDER BY provider, artist");
$current_provider = NULL;
while ($data = $service->fetch_object()) {
if ( $current_provider != $data->provider ) {
if ( $current_provider !== NULL ) {
echo '</div>';
}
echo '<div class="service">';
echo '<p class="lower">' . $data->provider . '</p>';
$current_provider = $data->provider;
}
echo '<a href="?artist=' . $data->artist '">' .
$data->artist . '</a><br/>';
}
echo '</div>';

How about that.
<?php $query = mysqli->query("SELECT * FROM `table`");
$current_group = array();
while ($data= $query->fetch_assoc()){
if(in_array($data['provider'],$current_group)){
echo "<h1>New Group" . $data['provider'] ."</h1>";
$current_group[] = $data['provider']
}
echo $data['artist'] . "<br/>";
}

Related

Interrupt and return repetition within the while multiple times

I'm not new here but I also do not ask questions because whenever I have a problem I find a solution in questions related here in the forum or in blogs, but I did not have any success with this problem.
In a database I have the tables posts and categories that are related, and in a single MySQL query I am displaying the title of the posts within their categories. So far so good, everything working. However within the while loop structure the tag with the is-sub class can not be repeated. Is there any way to stop the repetition of this while and then repeat it again?
I thank you for your help
echo '
<nav class="navbar">
<ul>';
$sql = Query("SELECT * FROM posts INNER JOIN categories ON post_category = category_id ORDER BY post_category, post_title");
$is_category = NULL;
while ($row = mysqli_fetch_assoc($sql)) :
if ($row['post_category'] != $is_category) {
echo '<li class="has-sub">' . $row['category_title'] . '';
$is_category = $row['post_category'];
}
// stop loop
echo '<ul class="is-sub">';
// return loop
echo '<li>' . $row['post_title'] . '</li>';
// stop loop
echo '</ul>';
// return loop
echo '</li>';
endwhile;
echo '
</ul>
</nav>';
If I understood what you are trying to do, I think the code below would work. If the is_sub tag is really meant to show only once then this could work:
<?php
echo '
<nav class="navbar">
<ul>';
$sql = Query("SELECT * FROM posts INNER JOIN categories ON post_category = category_id ORDER BY post_category, post_title");
$is_category = NULL;
$issub = false;
while ($row = mysqli_fetch_assoc($sql)) :
if ($row['post_category'] != $is_category) {
echo '<li class="has-sub">' . $row['category_title'] . '';
$is_category = $row['post_category'];
echo '<ul class="is-sub">';
}
if(!$issub) {
echo '<ul class="is-sub">';
$issub = true;
}
echo '<li>' . $row['post_title'] . '</li>';
echo '</ul>';
echo '</li>';
endwhile;
echo '
</ul>
</nav>';
?>

How to select an id bigger then

I'm working on a news system for a website. I used the news system from this tutorial: http://pixelcode.co.uk/tutorials/php/mysql-news-system/
So to display the news I use this line of code:
if(!$_GET['id'])
{
$query = mysql_query("SELECT * FROM news ORDER BY id DESC");
while($output = mysql_fetch_assoc($query))
{
echo '<div id="nieuws">';
echo '<a href="?id='.$output['id'].'" id="link">';
echo '<h1>'.$output['title'].'</h1>';
echo '<span id="date">'.date('d-m-y', $output['date']).'</span><br / >';
echo $output['shortnews'].'<br / >';
echo '</a>';
echo '</div>';
}
}
else
{
$id = $_GET['id'];
$query = mysql_query("SELECT * FROM news WHERE id='$id'");
$output = mysql_fetch_assoc($query);
?>
<form method="post" action="?id=<? echo $output['id']; ?>">
<h1><? echo $output['title']; ?></h1>
<? echo '<span id="date">'.date('d-m-y', $output['date']).'</span><br / >' ?>
<? echo $output['news']; ?>
</form>
<?php } ?>
I can do: if(!$_GET['id'] = 6) but I can't do this: if(!$_GET['id'] > 6). What's the problem? Or is there another code for bigger then an id?
Thanks for replying, MARCH
Operator precedence: ! binds tighter than ==, so you're effectively doing
(not($_GET) == 6)
That's why there's != for inequality tests.
If you'd used proper bracketing, e.g
(!($_GET['id'] == 6))
then you'd be doing
not(id == 6)
and get your expected results, because that's logically/functionally equivalent to id != 6
And note that you're vulnerable to sql injection attacks and are using an obsolete/deprecated DB interface.
Use isset():
if (isset($_GET['id'])) ...
Or, what I like to do:
// Get all possible arguments:
$id = #$_GET['id']; // The # prevents an error message
$foo = #$_GET['foo']; // foo means ... (explain the args)
...
// Later, as needed:
if (isset($id)) ...

PHP while loop split into two

I'm running a while loop which is taking rows from mySQL and echo'ing them out. Pretty standard. However, there needs to be different HTML markup for the first item, next two items, then it continues as normal into the while loop.
Currently, my while loop looking something like this:
while( ( $row = mysql_fetch_object( $result ) ) !== false )
{
// Places ad based of predefined variable frequency
if ($ad == $adFrequency){
echo '<div class="one-advertisement-article clearfix">';
echo '<div class="grid_9 suffix_2"><img src="http://placehold.it/263x75/000000/ffffff"></div>';
echo '<div class="grid_1"><a class="navigate-right-icon ss-icon" href="#">navigateright</a></div>';
echo '</div>';
$ad = 0;
}
echo '<div class="one-news-article clearfix">';
if( $row->imagelibid )
{
$imageid = intval( $row->imagelibid );
$image_result = mysql_query( "SELECT * FROM imagelib WHERE id = {$imageid}", $db );
$image_row = mysql_fetch_object( $image_result );
$image_url = "http://www.#.com/slir/w280/imagelib/" . $image_row->id . "_" . $image_row->filename;
echo '<div class="grid_4"><img src="'.$image_url.'"></div>';
}
else {
echo '<div class="grid_4"><div class="news-placeholder"><span class="ss-icon">ellipsischat</span></div></div>';
}
echo '<div class="grid_7">';
echo '<h2>'.$row->title.'</h2>';
$published_date = date('D, d M Y', strtotime($row->datein));
echo '<p class="published-date">'.$published_date.'</p>';
echo '</div>';
echo '<div class="grid_1">';
echo '<div class="news-item-vertical-sep"> </div>';
echo '<p></p>';
echo '</div>';
echo '</div>';
$ad++;
}
This works fine, but I need to take the first three news items and use this:
echo ' <div class="one-news-featured-article clearfix">';
echo ' <div class="grid_12">';
if( $row->imagelibid )
{
$imageid = intval( $row->imagelibid );
$image_result = mysql_query( "SELECT * FROM imagelib WHERE id = {$imageid}", $db );
$image_row = mysql_fetch_object( $image_result );
$image_url = "http://www.#.com/slir/w280/imagelib/" . $image_row->id . "_" . $image_row->filename;
echo '<div class="large-featured-image-container"><img src="'.$image_url.'">/div>';
}
echo ' <div>';
echo ' <h2>'.$row->title.'</h2>';
echo ' </div>';
echo ' </div>';
echo ' </div>';
echo ' <div class="grid_6">';
Any help? Essentially, it needs to apply the second code to the first three items in the query, then follow through with the code included in the current while loop - like an offset I guess.
Thanks,
R
This is quite simple. I hope I understood your question correctly:
$i = 0;
while ( ( $row = mysql_fetch_object( $result ) ) !== false ) {
if ($i < 3) {
// First code
} else {
// Second code
}
$i += 1;
}
Firstly, you should avoid using any mysql_ functions as they are all deprecated and will be removed from future versions of PHP. I'd recommend using PDO instead. See this tutorial to get started.
Then, it'll simply be a case of doing something like this:
foreach($db->query($query) as $index => $row) {
if ($index < 3) {
// first 3 items
} else {
// other items
}
}
You can do it easaly with an simple counter and an if statement:
$count = 0;
while(fetching) {
if($count < 3) {
// items 1, 2 and 3
} else {
// do normal
}
$count++;
}

Reduce number of MySQL Queries and Output Data in Correct Order

My main issue is the number of times I query the database (see below). Also, I would like to check that the current product (optionsToProducts.productID) has options for the current optionName before outputting the select statement! See the final image below to see the blank select box...
I have 8 tables in total, but the 3 that matter are:
optionNames
http://www.grabb.co.uk/stack/001.png
productOptions
http://www.grabb.co.uk/stack/002.png
optionsToProducts
http://www.grabb.co.uk/stack/003.png
<?php
$i=0;
$optionsquery = "SELECT * FROM optionNames WHERE categoryID = ".$categoryID."";
$optionsresult= mysql_query($optionsquery) or die(mysql_error());
while ($optionnames = mysql_fetch_array($optionsresult)) {
$i++;
$optionname = $optionnames["optionName"];
$optionID = $optionnames["optionNamesID"];
//echo $optionname."<br />";
?>
<label for="option<?php echo $i; ?>"><?php echo $optionname; ?></label>
<select name="option<?php echo $i; ?>" id="<?php echo $i; ?>">
<?php
//$optionvalues = "SELECT * FROM (optionsToProducts,productOptions) WHERE optionsToProducts.productID = ".$productID." AND productOptions.optionNamesID = ".$optionID."";
//echo $optionvalues."<br /><br />";
$optionvalues = "SELECT * FROM optionsToProducts WHERE productID = ".$productID."";
$valuesresult= mysql_query($optionvalues) or die(mysql_error());
while ($optionvals = mysql_fetch_array($valuesresult)) {
$valueName = $optionvals["optionValue"];
$valueID = $optionvals["productOptionsID"];
//echo $valueName."<br />";
$optionfinal = "SELECT * FROM productOptions WHERE productOptionsID = ".$valueID." AND optionNamesID = ".$optionID."";
$finalresult= mysql_query($optionfinal) or die(mysql_error());
while ($optionlast = mysql_fetch_array($finalresult)) {
$optionValueName = $optionlast["optionValue"];
$optionValueID = $optionlast["productOptionsID"];
$num_rows = mysql_num_rows($finalresult);
?>
<option value="<?php echo $optionValueID; ?>"><?php echo $optionValueName; ?></option>
<?php
}
}
echo "</select>";
}
?>
final Output:
http://www.grabb.co.uk/stack/004.png
As always, your help is appreciated. Thank you.
Since you tagged this question with the join tag, you probably know you need to write a join query to get what you need.
<?php
$i=0;
$query = "SELECT options.optionName, options.optionNamesID, po.optionValue, po.productOptionsID
FROM optionNames AS options
INNER JOIN productOptions AS po ON po.optionNamesID=options.optionNamesID
INNER JOIN optionsToProducts AS otp ON otp.productOptionsID=po.productOptionsID
WHERE otp.productID=" . (int) $productID
. " AND options.categoryID=" . (int) $categoryID;
$result = mysql_query($query);
if($result) {
$rows = array();
while($row = mysql_fetch_assoc($result) ) {
$rows[] = $row;
}
$i = 0;
$optionId = null;
foreach($rows as $row) {
if($optionId != $row['optionNamesID']) {
$optionId = $row['optionNamesID'];
?>
<label for="option<?php echo $optionId; ?>"><?php echo $row['optionName']; ?></label>
<select name="option<?php echo $optionId; ?>" id="<?php echo $optionId; ?>">
<?php } ?>
<option value="<?php echo $row['productOptionsID']; ?>"><?php echo $row['optionValue']; ?></option>
<?php
//Close select element when the optionNamesID changes or on the last row
if( (isset($rows[$i + 1]) && $rows[$i + 1]['optionNamesID'] != $optionId) ||
!isset($rows[$i + 1]) ) { ?>
</select>
<?php }
$i++;
}
} else {
//Debug query, remove in production
echo mysql_error();
}
?>
I also made some small changes - I use the optionNamesID in the select and label tag names - I don't know how you knew previously which select belonged to which option.
I also assumed that categoryID and productID came from somewhere, since it's not specified in the code.
Pushing all the rows to an array at the beginning is optional, but it makes the code a bit more organized (since you can check ahead in the array to see where to close the select tags).
NOTICE - this code is untested so there could some minor typos. Please make the needed corrections if necessary.

How do you create a form dropdown from a database table in php?

I am trying to code a function which creates a dropdown of school names selected from a database. It is doing fine creating a dropdown but it is not putting anything in the dropdown. Here is the code:
function schoolDD($name, $selected){
$select = '';
if( $selected != null )
{
$select = $selected;
}
$qry = "select *
from school
order by name, id
where display = 'Y'";
$schools = _execQry($qry);
$html = '<select name="'.$name.'" >';
foreach( $schools as $s ){
$html .= '<option value="'. $s['id'] .'"';
if( $select == $s['name'] ){
$html .= 'selected="selected"';
}
$html .= '>'. $s['name'] . '</option>';
}
$html .= '</select>';
return $html;
}
Problem solved. It was because in the query I had order before where. It should have been:
$qry = "select *
from school
where display = 'Y'
order by name, id";
Not:
$qry = "select *
from school
order by name, id
where display = 'Y'";
Looks OK but hard to say without knowing what _execQry does.
If you add the line
print_r($schools);
after you call _execQry, are you definitely retrieving results from the database?
Im glad you found your answer, but i haaattee php and html mixed together like that.
what about tsomethign like this...
<?php
$schools = getSchools();
$selectedSchool = 'sfgsfgd';
$name = 'asdfsafd';
?>
<select name="<?= $name ?>">
<?php foreach( $schools as $s ): ?>
<option value="<?= $s['id'] ?>"<?php if( $s['name'] == $selectedSchool ): ?> selected="selected"<?php endif; ?>><?= $s['name'] ?></option>
</select>

Categories