I was thought how to make a complicated (as I think) SELECT query from table with 3 kind of comments (first - positive comments, second - negative comments and third - neutral comments). Using PHP I would like to SELECT and diplay first negative comments, and right after negative comments diplay all other type of comments. How to diplay them with one SELECT query together with LIMIT that I use to separate for pagination?
Example of table:
id - unique id
type - (value 1-positive, 2-negative, 3-neutral)
text - value
I was thought first SELECT * FROM comments WHERE type='2' ORDER BY id LIMIT 0,100
while(){
...
}
Right after that second
SELECT * FROM commetns WHERE type!='2' ORDER BY id LIMIT 0,100
while(){
...
}
But how use LIMIT for pagination if there is two different SELECT queries?
Use a combination of UNION and LIMIT.
However, you need to determine the bind variables, and specify the number of rows you want to display.
(SELECT * FROM comments WHERE type = '2' LIMIT ?)
UNION
(SELECT * FROM comments WHERE type != '2' LIMIT ?);
SQLFiddle: http://sqlfiddle.com/#!9/6d682/1
Use an IF statement in the ORDER BY clause to change the type 2 to sort first:-
SELECT *
FROM comments
ORDER BY IF(type = 2, 0, type)
LIMIT 1, 20
This will give you all the negative (type 2) comments first, followed by the other comments (whether positive or neutral). You would probably want to add an extra column to the sort just for consistency of display.
I didn't get your case exactly, but I think you may use OR operator to get what you want:
SELECT * from comments WHERE type=2 OR type=-2 ORDER BY type DESC
you can use union to merge group of tables, but you must have the same columns in all the tables, for example:
select commetns,'nagtive' as type from nagtive_tbl limit 10
union
select commetns,'positive' as type from positive_tbl limit 10
union
select commetns,'neutral' as type from neutral_tbl limit 10
this query return table with all the comments from different tables each row contain is type so you can filter it while you building the lists on the client.
I must be missing context, otherwise you would just be fine using:
SELECT * from comments ORDER BY type ASC LIMIT 0,10
So by ordering the type, you'll first get all the items with type 1, followed by 2 and 3.
Just using the limit will chop them in the pieces you want and it will still respect the order.
Related
I have a PHP array with numbers of ID's in it. These numbers are already ordered.
Now i would like to get my result via the IN() method, to get all of the ID's.
However, these ID's should be ordered like in the IN method.
For example:
IN(4,7,3,8,9)
Should give a result like:
4 - Article 4
7 - Article 7
3 - Article 3
8 - Article 8
9 - Article 9
Any suggestions? Maybe there is a function to do this?
Thanks!
I think you may be looking for function FIELD -- while normally thought of as a string function, it works fine for numbers, too!
ORDER BY FIELD(field_name, 3,2,5,7,8,1)
You could use FIELD():
ORDER BY FIELD(id, 3,2,5,7,8,1)
Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found.
It's kind of an ugly hack though, so really only use it if you have no other choice. Sorting the output in your app may be better.
Standard SQL does not provide a way to do this (MySQL may, but I prefer solutions that are vendor-neutral so I can switch DBMS' at any time).
This is something you should do in post-processing after the result set is returned. SQL can only return them in an order specified in the "order by" clause (or in any order if there's no such clause).
The other possibility (though I don't like it, I'm honor-bound to give you the choice) is to make multiple trips to the database, one for each ID, and process them as they come in:
select * from tbl where article_id = 4;
// Process those.
select * from tbl where article_id = 7;
// Process those.
: : : : :
select * from tbl where article_id = 9;
// Process those.
You'll just need to give the correct order by statement.
SELECT ID FROM myTable WHERE ID IN(1,2,3,4) ORDER BY ID
Why would you want to get your data ordered unordered like in your example?
If you don't mind concatening long queries, try that way:
SELECT ID FROM myTable WHERE ID=1
UNION
SELECT ID FROM myTable WHERE ID=3
UNION
SELECT ID FROM myTable WHERE ID=2
I ran into an error I cant seem to come out of.
am not too good with unions
I want to loop through 4 different tables(using union all) and manipulate their values to fit my needs.
I also need to use single 'ORDER by Date DESC' (Date are integer values) for the whole union all, so that I can arrange the output in a pattern,
when I add the 'order by date desc ' to it, code doesn't work . and when I remove it , the values of the second query are attached to the names of the first query, am sooo confused.
I tried "Select * from table_name where..... it idnt work in this case , that's why I had to bring out all table_names I need to the query,
Basically , I want to echo each value from the query uniquely when I need to,
any help is appreciated, thanks
<?php
$q114="(SELECT id AS id1,text_post AS text_post1,likes AS likes1
FROM timeline_posts WHERE email='$owner_email')
UNION ALL (SELECT pic_comment AS pic_comment2, comments AS comments2, date AS date2
FROM pictures WHERE email='$owner_email')
UNION ALL (SELECT image AS image3,likes AS likes3, comments AS comments3
FROM profile_pics WHERE email='$owner_email')
UNION ALL (SELECT likes AS likes4, comments AS comments4, date AS date4
FROM friends_timeline_post WHERE timeline_email='$owner_email')
ORDER BY 'date' DESC";
$pages_query=mysqli_query($connect,$q114);
while($fetch9=mysqli_fetch_assoc($pages_query))
{
print_r($fetch9['likes3'] );
//a lot of work to be done here
}
?>
For "unioning" the results of multiple selects and ordering those results by a column name across all the results of the multiple selects, column names must be the same in all selects.
You could add a column to all selects that would contain your "digit" in order to still be able to distinguish between let say "likes1" and "likes2" even if their column name is "likes" for all the selects that you "unioned".
Im currently working on a project that requires MySql database and im having a hard time constructing the query that i want get.
i want to get the previous 10 rows from the specific WHERE condition on my mysql query.
for example
My where is date='December';
i want the last 10 months to as a result.
Feb,march,april,may,june,july,aug,sept,oct,nov like that.
Another example is.
if i have a 17 strings stored in my database. and in my where clause i specify that WHERE strings='eyt' limit 3
Test
one
twi
thre
for
payb
six
seven
eyt
nayn
ten
eleven
twelve
tertin
fortin
fiftin
sixtin
the result must be
payb
six
seven
Thanks in advance for your suggestions or answers
If you are using PDO this is the right syntax:
$objStmt = $objDatabase->prepare('SELECT * FROM calendar ORDER BY id DESC LIMIT 10');
You can change ASC to DESC in order to get either the first or the last 10.
Here's a solution:
select t.*
from mytable t
inner join (select id from mytable where strings = 'eyt' order by id limit 1) x
on t.id < x.id
order by t.id desc
limit 3
Demo: http://sqlfiddle.com/#!9/7ffc4/2
It outputs the rows in descending order, but you can either live with that, or else put that query in a subquery and reverse the order.
Re your comment:
x in the above query is called a "correlation name" so we can refer to columns of the subquery as if they were columns of a table. It's required when you use a subquery as a table.
I chose the letter x arbitrarily. You can use anything you like as a correlation name, following the same rules you would use for any identifier.
You can also optionally define a correlation name for any simple table in the query (like mytable t above), so you can refer to columns of that table using a convenient abbreviated name. For example in t.id < x.id
Some people use the term "table alias" but the technical term is "correlation name".
I'm new to this, sorry if the title is confusing. I am building a simple php/mysql gallery of sorts. It will show the newest 25 entries when a user first goes to it, and also allows off-site linking to individual items in the list. If the URL contains an ID, javascript will scroll to it. But if there are 25+ entries, it's possible that my query will fetch the newest results, but omit an older entry that happens to be in the URL as an ID.
That means I need to do something like this...
SELECT * FROM `submissions` WHERE uid='$sid'
But after that has successfully found the submission with the special ID, also do
SELECT * FROM `submissions` ORDER BY `id` DESC LIMIT 0, 25`
So that I can populate the rest of the gallery.
I could query that database twice, but I am assuming there's some nifty way to avoid that. MySQL is also ordering everything (based on newest, views, and other vars) and using two queries would break that.
You could limit across a UNION like this:
(SELECT * FROM submissions WHERE uid = '$uid')
UNION
(SELECT * FROM submissions WHERE uid <> '$uid' ORDER BY `id` LIMIT 25)
LIMIT 25
Note LIMIT is listed twice as in the case that the first query returns a result, we would have 26 results in the union set. This will also place the "searched for" item first in the returned sort result set (with the other 24 results displayed in sort order). If this is not desirable, you could place an ORDER BY across the union, but your searched for result would be truncated if it happened to be the 26th record.
If you need 25 rows with all of them being sorted, my guess is that you would need to do the two query approach (limiting second query to either 24 or 25 records depending on whether the first query matched), and then simply insert the uid-matched result into the sorted records in the appropriate place before display.
I think the better solution is:
SELECT *
FROM `submissions`
order by (case when usid = $sid then 0 else 1 end),
id desc
limit 25
I don't think the union is guaranteed to return results in the order of the union (there is no guarantee in the standard or in other databases).
I have a row in my db table that is datetime. How can i write a query to only all rows except one (the most recent).
I would have used
ORDER BY col_name DESC LIMIT 1
if i was choosing only the most recent.. but i actually require all but the most recent.
Thanks
Just select all rows but the first:
ORDER BY col_name DESC LIMIT 1, 18446744073709551615
See 13.2.9. SELECT Syntax which explains the LIMIT clause.
Title says:
MySQL Query to choose all but the most recent datetime
If have duplicated dates you'll have to go for:
select * from t
where val != (select max(val) from t);
This is because if there are 2 max values then limit will only filter the first one and you'll get the other max value in the resultset.