LIMIT LEFT JOIN TO ONE RECORD FROM ADDED TABLE - php

Now the result is that it`s showing same post as many times as many photos it has.
What to limit times of viewing same news??
function get_all_news(){
$query = $this->db->select('news.*, news_photos.name as news_photo_name, news_photos.ext as news_photo_ext')->from('news')->join('news_photos', 'news.id = news_photos.id_news', 'left')->order_by("date", "desc")->get();
}

Try to use DISTINCT or a GROUP BY on news.id.

Related

ORDER BY variable AFTER statement

Here is my code:
<?php
$data = mysql_query("SELECT * FROM board") or die(mysql_error());
while($info = mysql_fetch_assoc( $data ))
{
if(!empty($info['user'])){
Print "".$info['user'].""; }
else {
}
myOtherQuery($info['id']);
}
function myOtherQuery($id) {
$result3 = mysql_query("SELECT COUNT(source_user_id) FROM likes
INNER JOIN pins ON pins.id = likes.pin_id
WHERE pins.board_id='$id'");
$c = mysql_result($result3, 0); // Cumulative tally of likes for board
{
Print "$c";
}
}
?>
The first part gets a users name and board details (board as in a photo album).
the second part joins that data with another sql table that counts the number of likes that board has.
Both are displayed as a name and a score represented by a number.
By default they are ordered by the date of creation. I'd like to be able to order them by the score. However, since the score is determined in the second part of the code, I don't know how to achieve it. Is it possible?
The solution is of course to query both at once in the first place, via a LEFT JOIN against a subquery returning the count per board_id:
SELECT
board.*,
/* Your PHP code will retrieve the likes count via this alias `numlikes` as in $info['numlikes'] */
numlikes
FROM
board
LEFT JOIN (
/* Subquery returns count per board_id */
SELECT pins.board_id, COUNT(source_user_id) AS numlikes
FROM
likes
INNER JOIN pins ON pins.id = likes.pin_id
GROUP BY pins.board_id
) likes ON board.id = likes.board_id
ORDER BY numlikes
It is nearly always significantly more efficient to perform a single query rather than n queries in a loop. You should strive to do so whenever possible.
You can do it in one query
SELECT board.*, count(likes.source_user_id) as score
FROM board
INNER JOIN pins
ON pins.board_id = board.id
INNER JOIN likes
ON pins.id = likes.pin_id
ORDER BY score

two tables query, strange multiplication in the result

Hi and thanks in advance for your answer/s.
I have two tables, tracks(info on music tracks, title, lenght, cd_id..etc) and purchd_items(purchased tracks, cd_id, user_id..etc). I have this query:
function blue($id)
{
$user_id = $this->tank_auth->get_user_id();
$query = $this->db->query("SELECT tracks.id, tracks.track_id, tracks.cd_id, tracks.title, tracks.lenght, tracks.price, tracks.file, tracks.preview, tracks.hash, purchd_items.cd_id, purchd_items.name FROM tracks LEFT JOIN purchd_items ON tracks.cd_id = purchd_items.cd_id WHERE purchd_items.user_id = $user_id AND tracks.cd_id = $id GROUP BY tracks.title, purchd_items.name ORDER BY tracks.track_id");
return $query->result();
}
What I am trying to do check two tables for match and display all the info from tracks table as well as matching items from purchd_items table that will replace the entries from tracks table. If the user has already bought any tracks I want to display the download link instead of usual buy track link.Kind of like itunes, I guess.
I was sort of able to get this working using the query above but the number of items in the returned array was multiplied by the number of entries in the purchd_items table and I couldn't get rid of the duplicates.
Hope I am making sense here! Thank you!
I figured it out!
SELECT tracks.id, tracks.track_id, tracks.cd_id, tracks.title, tracks.lenght, tracks.price, tracks.file, tracks.preview, tracks.hash, purchd_items.cd_id, purchd_items.name FROM tracks LEFT JOIN purchd_items ON tracks.cd_id = purchd_items.cd_id AND purchd_items.name = tracks.title AND purchd_items.user_id = $user_id WHERE tracks.cd_id = $id ORDER BY tracks.id

Order by a SUM with multiple joins in codeigniter

Solution:
$query = $this->db->query("
SELECT *, SUM(views.times) AS sum
FROM channel
RIGHT JOIN video
ON channel.channel_id = video.channel_id
LEFT JOIN user
ON channel.user_id = user.user_id
LEFT JOIN views
ON channel.channel_id = views.channel_id
GROUP BY channel.channel_name
ORDER BY sum DESC
");
I have a query that returns a list of items.
function getfrontpage(){
$this->db->select('*');
$this->db->from('channel');
$this->db->join('video', 'channel.channel_id = video.channel_id' , 'right');
$this->db->join('user', 'channel.user_id = user.user_id');
$this->db->group_by("channel.channel_name");
$query = $this->db->get();
return $query->result();
}
Now i'm trying to order these with the SUM from another table, how can i achieve this?
Here is a picture from that table:
I want the results to be sorted by the SUM of the total of "times" for each "channel_id"
thanks in advance
I would suggest to run this through $this->db->query() instead.
It's nice to fetch simple values through CodeIgniters AR functions. But at some situations it's simply easier to build query strings instead.
In your case:
$query = $this->db->query("
SELECT channel_id, SUM(times) AS sum
FROM channel
GROUP BY channel_id
ORDER BY sum DESC
");
You can also escape most values through db->query()!
$this->db->query("
SELECT name
FROM table_name
WHERE id = ?
", array(1));
Isn't it as simple as $this->db->order_by("channel_id", "desc");? this orders the results by channel_id in descending order.
Assuming the table displayed in your question is called times_table, and has a key of user_id, channel_id, you can use the following code to join the times_table into your query so the "times" column is available to sort by.
$this->db->join("times_table", "times.user_id=channel.user_id, times.channel_id=channel.channel_id", "left");
// You've already grouped by channel_name, so grouping by channel_id is probably not necessary.
$this->db->order_by("SUM(times_table.times) DESC");
N.B. I just guessed the name of your displayed table is times_table.

mysql: group results, limit them and join to other tables in one query

i have a online application for wich i require a sort of dashboard (to use the white-space).
There are three tables used for the operation:
1.) categories: id, name
2.) entries: id, name, description, category_id, created, modified
3.) entryimages: id, filename, description, entry_id
on the dashboard i want to show 4-5 entries (with thumbnail images, so i require joins to the entryimages table and the categories table) for each category.
I read through some articles (and threads on s.o.) like this one:
http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
But am still not getting it right, i've tried to first extract all categories and for each and every category build a query and with "all union" attach them to one, but that is not working.
The last version of code i used:
foreach($categories as $id => $name)
{
$query .= "SELECT `entry`.`id`,
`entry`.`name`,
`entry`.`description`,
`entry`.`category_id`,
`entry`.`created`,
`entry`.`modified`,
`entryimages`.`filename`,
`entryimages`.`description`
FROM `entries` as `entry` LEFT JOIN `entryimages` ON `entryimages`.`entry_id` = `entry`.`id`
WHERE `entry`.`category_id` = $id ";
if($i < count($groups))
{
$query .= 'UNION ALL ';
}
$i++;
}
$result = mysql_query($query);
Does anybody know what is the best right to accomplish this operation?
Thanks 1000
On the dashboard if you want to show three entries, the way you are doing is wrong. If my understanding is right, the entire query will be something like
"SELECT `entry`.`id`,
`entry`.`name`,
`entry`.`description`,
`entry`.`category_id`,
`entry`.`created`,
`entry`.`modified`,
`entryimages`.`filename`,
`entryimages`.`description`
FROM `entries` as `entry`
INNER JOIN categories
ON (entry.category_id = categories.id)
LEFT JOIN (SELECT * FROM `entryimages` WHERE `entry_id` = `entry`.`id` LIMIT 1) AS `entryimages`
ON `entryimages`.`entry_id` =`entry`.`id`
ORDER BY `entry`.`created` DESC LIMIT 5";
Your code looks ok to me you should just add a LIMIT clause so that you get just five of them and an ORDER BY clause to get the latest
$query .= "SELECT `entry`.`id`,
`entry`.`name`,
`entry`.`description`,
`entry`.`category_id`,
`entry`.`created`,
`entry`.`modified`,
`entryimages`.`filename`,
`entryimages`.`description`
FROM `entries` as `entry` LEFT JOIN `entryimages` ON `entryimages`.`entry_id` = `entry`.`id`
WHERE `entry`.`category_id` = $id ORDER BY `entry`.`created` DESC LIMIT 5";

Select from one table, and count from another table in same query

I have quite a bit of knowledge about SQL queries.
I'm trying to make gallery, and I need to select categories from table "cat_photos", which contain rows (id,name,cover,photo) and count number of photos from table "photos" which contain rows (id,thumb,photo,category).
Here is code which i use:
1) Selecting categories
$query = mysql_query("SELECT * FROM cat_photos ORDER BY ID DESC");
while($data = mysql_fetch_array($query)) {
echo "<li><a href='photos.php?cat=$data[id]'><img src='galleries/categories/$row[image]' alt='$row[name]' /></a>
<div class='photodesc'><div class='catname'><a href='photos.php?cat=$row[id]'>$row[name]</a></div>
<div class='catcount'>Number of photos in category</div></div></li>"; }
2) Counting number of photos in category
$query = mysql_query("SELECT category, COUNT(photo) FROM photos GROUP BY category") or die(mysql_error());
while($row = mysql_fetch_array($query)){
echo "Number of photos is ". $row['COUNT(photo)'] ." in cateogry ". $row['category'] .".";
echo "<br />"; }
Separated all works, but I can't find a way to merge them into one query.
I have googleing for "UNION", "JOIN", "LEFT JOIN" options in MySql query but I could't together the pieces.
I wonder if this is in general possible?
How in order that query look like?
Try this, it should work :
SELECT cat_photos.*, count(photos.id) as number_photos
FROM cat_photos
LEFT JOIN photos ON photos.category = cat_photos.id
GROUP BY cat_photos.id, cat_photos.name, cat_photos.image
ORDER BY cat_photos.id
The number of photos will be accessible trough $row['number_photos'].
Just use your second query and join the wanted category elements.
Something quick and dirty would be:
SELECT c.category, COALESCE(COUNT(p.photo),0) as photos FROM photos p, cat_photos c
WHERE c.category = p.category
GROUP BY category
Since I don't know your exact database setup just change the selected elements to the ones you really need.
//edit: Put in Coalesce to get categories with 0 photos.
Don't SELECT *. Instead select individual columns and then join:
SELECT
cat_photos_main.id, cat_photos_main.category, cat_photos_main.photodesc, cat_photos_counts.num_photos
FROM cat_photos cat_photos_main
LEFT OUTER JOIN (SELECT category, count(*) AS num_photos FROM photos GROUP BY category) cat_photos_counts
ON cat_photos_main.category = cat_photos_counts.category

Categories