Order by date but add important at first in MySQL - mysql

I've a table what looks like that:
ID | title | author | timestamp | livetime | special
My goal is select all from table where livetime is larger than current timestamp and order it by timestamp desc BUT records where "special" is true must be in first (of course, also ordered). It's possible to do only with the MySQL?
My SQL Query looks that:
SELECT * FROM ads WHERE livetime > UNIX_TIMESTAMP() ORDER BY timestamp DESC

Yes, you can sort by two columns. Value of true is 1 and false 0, so you need to sort in the descending order.
SELECT * FROM ads WHERE livetime > UNIX_TIMESTAMP() ORDER BY special DESC, timestamp DESC

SELECT * FROM ads
WHERE livetime > UNIX_TIMESTAMP()
ORDER BY special <> 1,
timestamp DESC

Try this.
SELECT * FROM ads WHERE livetime > UNIX_TIMESTAMP() ORDER BY special, timestamp DESC

Related

How to select records from mysql along with one previous record

I have table like this
+----+----------------------+------------+
| id | desc | date |
+----+----------------------+------------+
| 15 | nah_i_kid | 2017-06-07 |
+----+----------------------+------------+
| 17 | it_is_just_the_cat | 2017-06-08 |
+----+----------------------+------------+
| 18 | thank_God | 2017-06-09 |
+----+----------------------+------------+
| 44 | no_kidding | 2017-06-10 |
+----+----------------------+------------+
My sql is
SELECT * FROM TABLE WHERE date between '2017-06-09' AND '2017-06-12'
I want the result should contain one previous record also (i-e record having id=17 take it example)
Thanks.
If you are using MYSQL, I have tried and it work good.
(select * from table where date < '2017-06-09' order by date desc limit 1 ) union (select * from table where date between '2017-06-09' AND '2017-06-12' order by date)
If you want the records from the previous date, you can do:
select t.*
from t
where date > (select max(t2.date) from t t2 where t2.date < '2017-06-09') and
date <= '2017-06-12';
This does what you want, assuming you have no duplicates on a date.
If you want exactly one row and you know the ids are assigned in chronological order, you can do:
select t.*
from t
where id > (select max(t2.id) from t t2 where t2.date < '2017-06-09') and
date <= '2017-06-12';
This solves the problem by taking the most recent previous record based on id.
If the ids are not in chronological order and you can have duplicates, the query gets more difficult. There is no definition of the "previous record". A union all is the best solution:
(select t.*
from t
where date < '2017-06-09'
order by date desc
limit 1
) union all
select t.*
from t
where date > >= '2017-06-09' and
date <= '2017-06-12'
I think this is what you're looking for.
The first part of the query is identical to yours, the second part gets all the values before your first date 2017-06-09, orders the values by date DESC, then limits the query to only take the topmost value using LIMIT 1.
SELECT
*
FROM table
WHERE `date` BETWEEN '2017-06-09' AND '2017-06-12'
OR `id` = (
SELECT
`id`
FROM table
WHERE `date` < '2017-06-09'
ORDER BY `date` DESC
LIMIT 1
)
I want the result should contain one previous record also (i-e record having id=17 take it example)
If you know that the rows are created in chronological order, and your id field is auto-increment, then you don't even need to use the date field, because you can assume that a higher id indicates a later record. So just cap your search on the id you want, and grab two rows:
SELECT * FROM TABLE WHERE id <= 17 ORDER BY id DESC LIMIT 2;
This has the added benefit of being fully indexed, which may not be the case if you introduce a WHERE clause on the date field.

DISTINCT ON query w/ ORDER BY max value of a column

I've been tasked with converting a Rails app from MySQL to Postgres asap and ran into a small issue.
The active record query:
current_user.profile_visits.limit(6).order("created_at DESC").where("created_at > ? AND visitor_id <> ?", 2.months.ago, current_user.id).distinct
Produces the SQL:
SELECT visitor_id, MAX(created_at) as created_at, distinct on (visitor_id) *
FROM "profile_visits"
WHERE "profile_visits"."social_user_id" = 21
AND (created_at > '2015-02-01 17:17:01.826897' AND visitor_id <> 21)
ORDER BY created_at DESC, id DESC
LIMIT 6
I'm pretty confident when working with MySQL but I'm honestly new to Postgres. I think this query is failing for multiple reasons.
I believe the distinct on needs to be first.
I don't know how to order by the results of max function
Can I even use the max function like this?
The high level goal of this query is to return the 6 most recent profile views of a user. Any pointers on how to fix this ActiveRecord query (or it's resulting SQL) would be greatly appreciated.
The high level goal of this query is to return the 6 most recent
profile views of a user.
That would be simple. You don't need max() nor DISTINCT for this:
SELECT *
FROM profile_visits
WHERE social_user_id = 21
AND created_at > (now() - interval '2 months')
AND visitor_id <> 21 -- ??
ORDER BY created_at DESC NULLS LAST, id DESC NULLS LAST
LIMIT 6;
I suspect your question is incomplete. If you want:
the 6 latest visitors with their latest visit to the page
then you need a subquery. You cannot get this sort order in one query level, neither with DISTINCT ON, nor with window functions:
SELECT *
FROM (
SELECT DISTINCT ON (visitor_id) *
FROM profile_visits
WHERE social_user_id = 21
AND created_at > (now() - interval '2 months')
AND visitor_id <> 21 -- ??
ORDER BY visitor_id, created_at DESC NULLS LAST, id DESC NULLS LAST
) sub
ORDER BY created_at DESC NULLS LAST, id DESC NULLS LAST
LIMIT 6;
The subquery sub gets the latest visit per user (but not older than two months and not for a certain visitor21. ORDER BY must have the same leading columns as DISTINCT ON.
You need the outer query to get the 6 latest visitors then.
Consider the sequence of events:
Best way to get result count before LIMIT was applied
Why NULLS LAST? To be sure, you did not provide the table definition.
PostgreSQL sort by datetime asc, null first?

MySQL Order by Date, with NULL first

I have a select statement that I would like to select 1 record from a table. The structure is:
id | start_time
--------------
1 NULL
2 2014-08-23
3 2014-09-01
I would like to select the item with a NULL start time, but if that does not exist I would like it to select the latest start_time. I have tried using ORDER with LIMIT 1, but using ORDER BY start_time either gives NULL first followed by the earliest starting, or latest starting then NULL. Is it possible to have result order 1,3,2 ?
You can use two sort expressions to get the ordering you want:
select t.*
from table t
order by (start_time is null) desc,
start_time desc
limit 1;
You can have two different ORDER BY expressions:
SELECT * from table ORDER BY (start_time IS NULL) DESC, start_time DESC;

Select last N rows from MySQL

I want to select last 50 rows from MySQL database within column named id which is primary key. Goal is that the rows should be sorted by id in ASC order, that’s why this query isn’t working
SELECT
*
FROM
`table`
ORDER BY id DESC
LIMIT 50;
Also it’s remarkable that rows could be manipulated (deleted) and that’s why following query isn’t working either
SELECT
*
FROM
`table`
WHERE
id > ((SELECT
MAX(id)
FROM
chat) - 50)
ORDER BY id ASC;
Question: How is it possible to retrieve last N rows from MySQL database that can be manipulated and be in ASC order ?
You can do it with a sub-query:
SELECT * FROM
(
SELECT * FROM table ORDER BY id DESC LIMIT 50
) AS sub
ORDER BY id ASC;
This will select the last 50 rows from table, and then order them in ascending order.
SELECT * FROM table ORDER BY id DESC LIMIT 50
save resources make one query, there is no need to make nested queries
SELECT * FROM table ORDER BY id DESC, datechat DESC LIMIT 50
If you have a date field that is storing the date (and time) on which the chat was sent or any field that is filled with incrementally (order by DESC) or de-incrementally (order by ASC) data per row put it as second column on which the data should be ordered.
That's what worked for me!!!! Hope it will help!!!!
Use it to retrieve last n rows from mysql
Select * from tbl order by id desc limit 10;
use limit according to N value.
if anyone need this
you can change this into
SELECT
*
FROM
`table`
WHERE
id > ((SELECT
MAX(id)
FROM
chat) - 50)
ORDER BY id ASC;
into
SELECT
*
FROM
`table`
WHERE
id > (SELECT MAX(id)- 50 FROM chat)
ORDER BY id ASC;
select * from Table ORDER BY id LIMIT 30
Notes:
* id should be unique.
* You can control the numbers of rows returned by replacing the 30 in the query

Select specific rows MySQL

How can I select specific rows in a MySQL Table? So instead of selecting ... ORDER BY date can I do something like SELECT * FROM Posts FROM(5) TO(10) ORDER BY date DESC where I would be selecting Posts 5 to 10 in the descending order?
Your question is a little ambiguous. There are two possibilities:
You want only part of the results to be retrieved from the database, for example from the 5th one to the 10th one:
SELECT * FROM `posts` ORDER BY `date` DESC LIMIT 6 OFFSET 4
which will skip the 4 first results and given you next 6 results (beginning with 5th from the original set and ending with 10th from the original set).
You want results with specific IDs between 5 (inclusive) and 10 (inclusive):
SELECT * FROM `posts` WHERE `id` BETWEEN 5 AND 10 ORDER BY `date` DESC
or (which can be useful if the list of IDs is not the whole range):
SELECT * FROM `posts` WHERE `id` IN (5,6,7,8,9,10) ORDER BY `date` DESC
but this last example is only to show you different way of picking "specific" rows.
use limit:
SELECT * FROM Posts ORDER BY date DESC LIMIT 5, 5
http://php.about.com/od/mysqlcommands/g/Limit_sql.htm
You can use limit operator in mysql to do this. Ex: SELECT * FROM posts LIMIT 5 , 5;
Alternative Syntax which is more readable in my opinion:
SELECT * FROM Posts ORDER BY date DESC LIMIT 5 OFFSET 5
The first number indicates the number of results returned, the second one defines the offset from where to begin with.
If you use the LIMIT 5,5 it's the other way round.
You can use the limit:
SELECT * FROM tabel ORDER BY date DESC LIMIT 5,5
(5th till 10th record based on descending date).
SELECT * FROM Posts ORDER BY date DESC limit 5, 10