Combine 2 MySQL select statements both using LIMIT - php

I'm making a feed wall, and two services save posts to the same database table.
One posting service is used way more than the other, so on the wall I want to limit each service to the 25 newest posts (total 50) on the front page for equal representation.
This is what I originally had, without evening the posts:
$sql = "SELECT * FROM posts";
$sql .= " WHERE disq = 0";
$sql .= " AND approved = 1";
$sql .= " ORDER BY created_at DESC";
$sql .= " LIMIT 50";
but then I try to limit them by service:
$sql_1 = "SELECT * FROM posts";
$sql_1 .= " WHERE disq = 0";
$sql_1 .= " AND approved = 1";
$sql_1 .= " AND source = 'TW'";
$sql_1 .= " ORDER BY created_at DESC";
$sql_1 .= " LIMIT 25";
$sql_2 = "SELECT * FROM posts";
$sql_2 .= " WHERE disq = 0";
$sql_2 .= " AND approved = 1";
$sql_2 .= " AND source = 'IG'";
$sql_2 .= " ORDER BY created_at DESC";
$sql_2 .= " LIMIT 25";
Doing something like
$sql = $sql_1 UNION $sql_2;
Doesn't seem to work, because all the examples I see perform LIMIT at the end of a bunch of queries. And an ORDER BY should be performed after that, to reorder the posts chronologically and make the wall mixed service.
MySQL help is appreciated

You could omit your ORDER BY in your subqueries and just do it at the end, after the union.
(
SELECT * FROM POSTS
WHERE disq = 0 AND approved = 1 AND source= 'TW'
LIMIT 25
)
UNION ALL
(
SELECT * FROM POSTS
WHERE disq = 0 AND approved = 1 AND source= 'IG'
LIMIT 25
)
ORDER BY created_at DESC
More info on the union and how to sort is explained at this MySQL documentation

You need to pull the most recent 25 items separately from your two criteria sets, then put them together and order them again.
That will go like this. You need these parenthetical subqueries because the ORDER BY ... LIMIT clauses need to be associated with each one separately.
SELECT *
FROM
( SELECT *
FROM POSTS
WHERE disq = 1 AND approved = 1 AND source= 'TW'
ORDER BY created_at DESC
LIMIT 25
) A
UNION ALL
( SELECT *
FROM POSTS
WHERE disq = 1 AND approved = 1 AND source= 'IG'
ORDER BY created_at DESC
LIMIT 25
) A
ORDER BY created_at DESC, source
An index on your POSTS table on (disq, approved, source, created_at) will serve to speed up this query.

Related

CodeIgniter get table count rows

I am new in CodeIgniter, I want to count all rows from database table but i use limit in query and i want all count without use limit how can i do ?
my code is below :
$sql = " SELECT intGlCode,fkCategoryGlCode,'C' as acctyp,varEmail,varContactNo as phone,CONCAT(varFirstName,' ',varLastName) as name,dtCreateDate,chrStatus,varMessage as message
FROM " . DB_PREFIX . "Customer WHERE varEmail='$userEmail'
UNION
SELECT intGlCode,'' as fkCategoryGlCode,'P' as acctyp,varEmail,varPhoneNo as phone,varName as name,dtCreateDate,chrStatus,txtDescription as message FROM
" . DB_PREFIX . "Power WHERE varEmail='$userEmail' ORDER BY intGlCode DESC
LIMIT $start, $per_page ";
$query = $this->db->query($sql)
i use limit for pagination but i want to get all record from table.
You can add new column in both above and below UNION queries. It will be like below.
select (select count(*) from your_query), your_columns from query_above_union
UNION
select (select count(*) from your_query), your_columns from query_below_union
your_query = your full actual query your are using currently.
Although I am not sure about Codeigniter. But sure about SQl.
* If you count all records with all data including limit, than you can use this code. please check it. I hope it will works for you.*
$countsql = " SELECT intGlCode,fkCategoryGlCode,'C' as acctyp,varEmail,varContactNo as phone,CONCAT(varFirstName,' ',varLastName) as name,dtCreateDate,chrStatus,varMessage as message
FROM " . DB_PREFIX . "Customer WHERE varEmail='$userEmail'
UNION
SELECT intGlCode,'' as fkCategoryGlCode,'P' as acctyp,varEmail,varPhoneNo as phone,varName as name,dtCreateDate,chrStatus,txtDescription as message FROM
" . DB_PREFIX . "Power WHERE varEmail='$userEmail' ORDER BY intGlCode DESC";
$sql = $countsql. " LIMIT $start, $per_page";
$totalRecords = $this->db->query($countsql);
$result["total_rows"] = $totalRecords->num_rows();
$query = $this->db->query($sql);
$result["list"] = $query->result_array();

I want to have data from 2 tables in MySQL ordered by date

I would like to get data from two tables in MySQL, ordered by date.
$sql = "
SELECT
items.*, invoice.*
FROM
items
JOIN
invoice
ON
items.user_id = invoice.buyer_id
WHERE
items.user_id = '$user_id'"
LIMIT
10
ORDER BY
date;
";
Try with:
$sql = "SELECT *";
$sql .= " FROM items, invoice";
$sql .= " WHERE items.user_id = invoice.buyer_id";
$sql .= " AND items.user_id = '$user_id'";
$sql .= " ORDER BY date DESC";
$sql .= " LIMIT 10";
Also it is better if you use it as a prepared statement instead of having the variable inside the SQL query to avoid SQL injection.

Where clause stopped working

I have this code that (without the WHERE, was working) How do I get it to work with the WHERE clause ?
I just need it to only list lines that is current and max 2 years ahead.
$SQL = "SELECT ";
$SQL .= "SUM(Bookings.Spots) as SUMSPOT, Trips.ID, Bookings.FK_ID, Trips.MaxSpots, ";
$SQL .= "Trips.Tripnr, Trips.StartDate, Trips.EndDate, Trips.StartLocation, ";
$SQL .= "Trips.DestinationDK, Trips.PricePerSpot ";
$SQL .= "FROM Trips WHERE Trips.EndDate >= NOW() AND Trips.EndDate < DATE_ADD(NOW(), INTERVAL 2 YEAR) ";
$SQL .= "LEFT JOIN Bookings on Bookings.FK_ID = Trips.ID ";
$SQL .= "GROUP BY Trips.ID, Bookings.FK_ID ORDER BY Trips.StartDate ASC ";
You need to add the WHERE clause after the LEFT JOIN and before the GROUP tag.
You can check the documentation here for more answers as to where you can put which keyword.

Joining 5 tables in SQL in a PHP function

What I'm trying to return in a set: The lessonIDs associated to the userID and schoolID within a given startTime and endTime.
This is to be displayed on a calendar. I only want to display the lessons that are associated to the user viewing it for a selected school within the time range they are viewing on the calendar.
This data is just dummy data to show the table structure and data types.
Lesson Table:
lessonID roomFK startTime endTime
1 2 2014-08-01 13:00:00 2014-08-01 14:00:00
2 3 2014-08-01 13:00:00 2014-08-01 14:00:00
Room Table:
roomID schoolFK
1 1
2 1
3 2
4 2
School Table:
schoolID
1
2
User Table:
userID
1
2
3
Lesson/Teacher Junction Table:
lessonFK teacherFK
1 1
1 2
2 3
What I've tried:
function find_lessons_by_school_id_and_teacher_id_ranged_feed($school_id, $teacher_id, $start, $end) {
global $connection;
$school_id = mysqli_real_escape_string($connection, $school_id);
$teacher_id = mysqli_real_escape_string($connection, $teacher_id);
$start = mysqli_real_escape_string($connection, $start);
$end = mysqli_real_escape_string($connection, $end);
$start = strftime("%Y-%m-%d %H:%M:%S", $start);
$end = strftime("%Y-%m-%d %H:%M:%S", $end);
$query = "SELECT * ";
$query .= "FROM lesson ";
$query .= "JOIN room ON lesson.roomFK = room.roomID ";
$query .= "JOIN school ON room.schoolFK = school.schoolID ";
$query .= "JOIN user ON user.userID = junc_lesson_teacher.teacherFK ";
$query .= "JOIN junc_lesson_teacher ON junc_lesson_teacher.lessonFK = lesson.lessonID ";
$query .= "WHERE room.schoolFK = '{$school_id}' ";
$query .= "AND lesson.startTime >= '{$start}' ";
$query .= "AND lesson.endTime <= '{$end}' ";
$query .= "AND user.userID = '{$teacher_id}' ";
$query .= "ORDER BY lesson.roomFK ASC";
$set = mysqli_query($connection, $query);
return $set;
}
When I run this, mySQL complains about the query statement.
Any input on how to do this properly would be greatly appreciated! Thanks!
The order of your join operations is wrong. You've got to swap the last two ones. Instead of
$query .= "FROM lesson ";
$query .= "JOIN room ON lesson.roomFK = room.roomID ";
$query .= "JOIN school ON room.schoolFK = school.schoolID ";
$query .= "JOIN user ON user.userID = junc_lesson_teacher.teacherFK ";
$query .= "JOIN junc_lesson_teacher ON junc_lesson_teacher.lessonFK = lesson.lessonID ";
write
$query .= "FROM lesson ";
$query .= "JOIN room ON lesson.roomFK = room.roomID ";
$query .= "JOIN school ON room.schoolFK = school.schoolID ";
$query .= "JOIN junc_lesson_teacher ON junc_lesson_teacher.lessonFK = lesson.lessonID ";
$query .= "JOIN user ON user.userID = junc_lesson_teacher.teacherFK ";
because every table you use in a join must be introduced first. By your statement you can't use junc_lesson_teacher to join the user table, so you've got to join junc_lesson_teacher before you join user. Think of your tables as a chain without interrupts.
If you had a moderately sensible naming policy, that query might look like this...
$query = "
SELECT columns
, i
, actually
, want
FROM lesson l
JOIN room r
ON r.room_id = l.room_id
JOIN school s
ON s.school_id = r.school_id
JOIN lesson_teacher lt -- <-- NOTE TABLES SWAPPED AROUND
ON lt.lesson_id = l.lesson_id
JOIN user u
ON u.user_id = lt.teacher_id -- <-- SEE?
WHERE r.school_id = $school_id
AND l.startTime >= '$start'
AND l.endTime <= '$end'
AND u.user_id = $teacher_id
ORDER
BY l.room_id ASC;
";
$set = mysqli_query($connection, $query)
or die(mysqli_error($connection)); -- for development only
instead of
$query = "SELECT * ";
write all of required fields from all tables
$query = "SELECT lesson.roomFK,room.roomID,school.schoolID,room.schoolFK,user.userID,junc_lesson_teacher.teacherFK,junc_lesson_teacher.lessonFK,lesson.lessonID";

Where do I insert the ORDER BY in my MYSQL query

I need to have my results sorted by "ORDER BY prod_name" in my SQL statement but I cannot figure out get it to work. I tried after
$thisProduct .= " AND prod_type = 1 ORDER BY prod_name";
and also after
$thisProduct .= " AND ID = '" . mysql_real_escape_string($_GET['product']) . "' ORDER BY prod_name";
But I cannot get my results to sort correctly. Am I placing the order by in the wrong spot or did I query the DB incorrectly?
Thank you in Advance, I am still pretty new at MYSQL queries.
$thisProduct = "SELECT prod_name AS Name, days_span, CONCAT(LEFT(prodID,2),ID) AS ID, geo_targeting FROM products WHERE status = 'Active' AND vendID = ".$resort['vendID'];
if (isset($_GET['product']) AND is_numeric($_GET['product'])) {
$thisProduct .= " AND ID = '" . mysql_real_escape_string($_GET['product']) . "'";
}
else {
$thisProduct .= " AND prod_type = 1";
}
$thisProduct .= " LIMIT 1";
$getThisProduct = mysql_query($thisProduct);
if (!$getThisProduct/* OR mysql_num_rows($getThisProduct) == 0 */) {
header("HTTP/1.0 404 Not Found");
require APP_PATH . '/404.html';
die();
}
$thisProductData = mysql_fetch_assoc($getThisProduct);
You should have:
$thisProduct .= " ORDER BY prod_name";
$thisProduct .= " LIMIT 1";
(Note that the LIMIT 1 means you only get one record).
Assuming that your query is correct and you want the first product by name:
$thisProduct .= " ORDER BY prod_name LIMIT 1";
I believe it should go right before your "LIMIT 1", as in:
$thisProduct .= " ORDER BY prod_name LIMIT 1";
Insert it before the LIMIT
$thisProduct .= " ORDER BY prod_name LIMIT 1";
You can the select syntax at http://dev.mysql.com/doc/refman/5.0/en/select.html
SELECT query usually takes following form
SELECT which_all_to_select
FROM which_table/tables
WHERE criteria
ORDER BY column_name ASC/DESC;
ASC ascending order, and DESC is descending order
This orders query results by column_name specified in ORDER BY clause .

Categories