select from 2 table and make ordering them - php

first, sorry for my English ...
what i want is to select from two SQL tables and then make them in a specific order , like in forums ...
i have two table, topic and users, i want to select from both of them a putt author info next to his topic
here is the SQL of Topic and users
CREATE TABLE IF NOT EXISTS `topics` (
`id` int(11) NOT NULL,
`id2` int(11) NOT NULL,
`title` varchar(256) NOT NULL,
`message` longtext NOT NULL,
`author_id` int(11) NOT NULL,
`timestamp` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint(20) NOT NULL,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`avatar` varchar(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
and the php code might look like this
<?php
$sql = mysql_query(' MySQL query ... ');
while($row = mysql_fetch_array($sql)) {
echo '<p>'.$row['username']'<br>';
echo $row['message'].'<br></p>';
}
?>
is there any way to do it ??

As I understood, what you are looking for is the correct SQL statement to execute. The following simple solution will.
<?php
$sql = mysql_query('SELECT users.username, topics.message FROM `users` INNER JOIN topics ON topics.author_id = users.id');
while($row = mysql_fetch_array($sql)) {
echo '<p>'.$row['username']'<br>';
echo $row['message'].'<br></p>';
}
?>

SELECT * FROM `users` INNER JOIN topics ON topics.author_id = users.id'

Related

Get notifications from database

im making an notification system, and i can't get them outputted.
I have following code:
public function getNotification() {
$sth = $this->dbh->prepare("SELECT n.to_uid as `notif_to_uid`, n.status as `notif_status`, n.time as `notif_time`, u.id as `user_id`, u.name as `user_name` FROM notifications n INNER JOIN users u ON u.id = n.to_uid WHERE u.id = :uid n.type = 'friendrequest'");
$sth->execute(array(
':uid' => $_SESSION['uid']
)
);
if($notifications = $sth->fetchAll(PDO::FETCH_OBJ)) {
foreach($notifications as $notification) {
echo 'New notification ect. ect.';
}
}
}
My tables looks like this:
CREATE TABLE `notifications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`from_uid` int(11) NOT NULL,
`to_uid` int(11) NOT NULL,
`type` enum('friendrequest','gameinvite','update') NOT NULL,
`status` enum('unseen','seen') NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) NOT NULL,
`password` varchar(155) NOT NULL,
`firstname` varchar(255) NOT NULL,
`lastname` varchar(255) NOT NULL,
`gender` varchar(255) NOT NULL,
`points` varchar(255) DEFAULT '0',
PRIMARY KEY (`id`)
);
Right now it isnt outputting anything, and the connection to the db does work.
Try to display query errors by
$execute = $sth->execute(array(
':uid' => $_SESSION['uid']
)
);
if(!$execute){
print_r($sth->errorInfo());
}
I see you have lost "AND" or "OR" here
WHERE u.id = :uid n.type = 'friendrequest'

Select two columns from two tables and order by their values DESC

With this code I'm getting news from the database and order it by column "views":
<?php
$getnewsinfo = mysql_query("SELECT * FROM news ORDER BY views DESC LIMIT 5");
while($newsinforow = mysql_fetch_array($getnewsinfo))
{
$newsid = $newsinforow['id'];
$title = $newsinforow['title'];
$author = $newsinforow['author'];
$date = date('d.m.Y', $newsinforow['date']);
$picture = $newsinforow['picture'];
$picture_desc = $newsinforow['picture_desc'];
$category = $newsinforow['category'];
$text = $newsinforow['text'];
?>
Now I want to order the news by views and by the number of comments, but I have no idea how.
Here is my database structure :
CREATE TABLE IF NOT EXISTS `news` (
`id` int(11) NOT NULL auto_increment,
`views` int(11) NOT NULL default '0',
`title` varchar(255) NOT NULL,
`author` varchar(255) NOT NULL,
`date` varchar(255) NOT NULL,
`picture` varchar(255) NOT NULL,
`picture_desc` varchar(255) NOT NULL,
`category` varchar(255) NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
CREATE TABLE IF NOT EXISTS `news_comments` (
`id` int(11) NOT NULL auto_increment,
`news_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`website` varchar(255) NOT NULL,
`text` text NOT NULL,
`date` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;
I also want to ask you... do you have any comments on the code and database structure ?
Try this sql
SELECT n.*,count(nc.id) as cnt FROM news as n, news_comments as nc where n.id = nc.news_id group by nc.news_id ORDER BY views DESC,cnt DESC LIMIT 5

"my network" function with sql subquery

I need a little help for one sql query;
here is my basic user database table
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(100) NOT NULL,
`pass` varchar(255) NOT NULL,
`fname` varchar(50) NOT NULL,
`lname` varchar(40) NOT NULL,
`network` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=27 ;
and here is my basic topics database table
CREATE TABLE IF NOT EXISTS `topics` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` varchar(100) NOT NULL,
`title` varchar(255) NOT NULL,
`body` text,
`tags` varchar(256) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
What I'm trying to do is;
i.e. list all topics from users who joined "harvard" network
You just need a simple JOIN. Join the tables on the userID (of those who are in "harvard").
SELECT title,body
FROM topics, users
WHERE userid = users.id
AND network = 'harvard'
Or using the JOIN keyword:
SELECT title,body
FROM topics
JOIN users ON userid = users.id
WHERE network = 'harvard'
This should do the trick, I think:
SELECT
title
FROM
topics t
INNER JOIN
users u ON t.userid=u.id
WHERE
network='Harvard'
SELECT t.title
FROM users u
INNER JOIN topics t ON u.id = t.userid
WHERE u.network = 'harvard'
GROUP BY u.id

Recipe Finder with PHP and MySQL based on Ingredients

I am developing a cooking recipe-website and i want to create a recipe finder based on the used incredients.
My current finder only works with 3 ingredients right.
The Finder should return the right recipe(s) based on the used incredients (should work with 1-n*)
My Tables:
CREATE TABLE IF NOT EXISTS `INGREDIENTS` (
`ingredients_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`ingredients_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;
CREATE TABLE IF NOT EXISTS `INGREDIENTS_POS` (
`ingredients_pos_id` int(11) NOT NULL AUTO_INCREMENT,
`ingredients_id` int(11) NOT NULL,
`ingredients_unit` varchar(20) NOT NULL,
PRIMARY KEY (`ingredients_pos_id`),
KEY `ingredients_detail_fk` (`ingredients_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;
CREATE TABLE IF NOT EXISTS `RECIPES` (
`recipes_id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(50) COLLATE utf8_bin NOT NULL,
`text` varchar(2000) COLLATE utf8_bin NOT NULL,
`count_persons` int(11) NOT NULL,
`duration` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`date` datetime NOT NULL,
`accepted` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`recipes_id`),
KEY `recipes_user_fk` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=88 ;
CREATE TABLE IF NOT EXISTS `RECIPES_POS` (
`recipes_pos_id` int(11) NOT NULL AUTO_INCREMENT,
`recipes_id` int(11) NOT NULL,
`ingredients_id` int(11) NOT NULL,
`ingredients_value` int(11) NOT NULL,
PRIMARY KEY (`recipes_pos_id`),
KEY `recipe_pos_rec_id` (`recipes_id`),
KEY `recipes_pos_ingredient_fk` (`ingredients_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=58 ;
My buggy Solution (doesn't support count from 1-n):
<?php
include 'db_connect.php';
$q = urldecode(mysql_real_escape_string($_GET['q']));
$parameter = explode ('$',$q);
$var = 0;
//print_r($parameter);
foreach($parameter as $ing)
{
//echo $ing;
$sql = "SELECT ingredients_id FROM INGREDIENTS WHERE name='".$ing."'";
$result = mysql_query($sql,$db) or exit('{"Data":null,"Message":null,"Code":500}');
$row = mysql_fetch_array($result);
$arr_id[$var] = $row['ingredients_id'];
$var++;
}
//print_r($arr_id);
$sql = "SELECT r.recipes_id FROM RECIPES r, RECIPES_POS rp WHERE r.recipes_id = rp.recipes_id ";
foreach($arr_id as $id)
{
$sql .= "AND rp.ingredients_id =".$id . " ";
}
//echo $sql;
$result = mysql_query($sql,$db) or exit('{"Data":null,"Message":null,"Code":500}');
mysql_close($db);
$rec;
while($row = mysql_fetch_array($result))
{
//echo "test";
$_GET['id'] = $row['recipes_id'];
$rec= include('get_recipe_byID.php');
}
//print_r(mysql_fetch_array($result));
if (count($arr_id) == 0)
{
echo '{"Data":null,"Message":null,"Code":404}';
die();
}
?>
I need a better solution for that chase.
Maybe SQL itself will help me to find the right recipes
thx
That query helped me a lot:
select r.recipes_id
from RECIPES r
inner join RECIPES_POS rp on r.recipes_id = rp.recipes_id
where rp.ingredients_id in (4, 6)
group by r.recipes_id
having count(distinct rp.ingredients_id) = 2

SQl query to select relational data

I am trying to write the SQL that selects all products and available features.
My database is as follows:
CREATE TABLE IF NOT EXISTS `products` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`product_name` varchar(255) NOT NULL,
`product_description` varchar(255) NOT NULL,
`product_weight` varchar(255) NOT NULL,
`product_price` decimal(11,2) NOT NULL,
`product_image` varchar(255) NOT NULL,
PRIMARY KEY (`product_id`)
);
CREATE TABLE IF NOT EXISTS `features` (
`feature_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`feature_uri` varchar(255) NOT NULL,
`feature_name` varchar(100) NOT NULL,
`feature_title` varchar(150) DEFAULT NULL,
`feature_body` text,
`feature_body_short` varchar(255) DEFAULT NULL,
`feature_image` varchar(255) DEFAULT NULL,
`parent_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`feature_id`),
UNIQUE KEY `feature_uri_UNIQUE` (`feature_uri`),
KEY `parentFK` (`feature_id`),
FULLTEXT KEY `feature_name_FT` (`feature_name`),
FULLTEXT KEY `feature_body_FT` (`feature_body`)
);
CREATE TABLE IF NOT EXISTS `feature_products` (
`feature_product_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`feature_product_order` smallint(6) DEFAULT NULL,
`feature_product_standard` tinyint(1) NOT NULL,
`feature_id` int(11) unsigned NOT NULL,
`product_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`feature_product_id`),
KEY `productFK` (`product_id`),
KEY `featureFK` (`feature_id`)
);
I would like to be able to do this in one loop e.g:
{foreach}
<tr>
<td>{name}</td>
<td>{weight}</td>
<td>{if product_id == 1}yes{/if}</td>
<td>{if product_id == 2}yes{/if}</td>
etc
<tr>
{/foreach}
I am using Zend, if this can be of use.
Trying to achieve this HTML:
UPDATE:
Non of the suggested answers are working, instead I managed to hack it to work like this:
SELECT
p.*,
(
SELECT
GROUP_CONCAT(f.feature_id SEPARATOR ', ')
FROM feature_products fp
LEFT JOIN features f ON f.features_id = fp.feature_id
WHERE fp.product_id = p.product_id
LIMIT 1
) as features
FROM product p
Although the problem with the above code is that it does not return 'feature_product_standard'
I'm assuming that you have MySQL, dunno about Zend, but this should get you started.
SELECT
p.product_name
, p.product_description
, p.product_weight
, p.product_price
, p.product_image
, GROUP_CONCAT(f.feature_id ORDER BY f.feature_id) as feature_ids
, GROUP_CONCAT(f.feature_name ORDER BY f.feature_id) as feature_names
FROM products p
LEFT JOIN feature_products fp ON (fp.product_id = p.product_id)
LEFT JOIN features f ON (f.feature_id = fp.feature_id)
GROUP BY p.product_id
Not very good code i know, but i hope it helps.
This is using Johan's SQL code.
I haven't tested this.
$connection = odbc_connect("Connection info here");
$query = "SELECT
p.product_name
, p.product_description
, p.product_weight
, p.product_price
, p.product_image
, GROUP_CONCAT(f.feature_id ORDER BY f.feature_id) as feature_ids
, GROUP_CONCAT(f.feature_name ORDER BY f.feature_id) as feature_names
FROM products p
LEFT JOIN feature_products fp ON (fp.product_id = p.product_id)
LEFT JOIN features f ON (f.feature_id = fp.feature_id)";
$result = odbc_exec($connection, $query);
while ($data[] = odbc_fetch_array($result));
odbc_close($connection);
if ($data[0]["product_name"]) {
echo "<table><tr>";
foreach (array_keys($data[0]) as $a) { $message .= "<th>".$a."</th>"; }
foreach ($data as $d) {
if ($d["product_name"]) {
if ($d) {
echo "</tr><tr>\n";
foreach ($d as $s) {
echo "<td>".$s."</td>";
}
}
}
}
}

Categories