I need to sort a postgres table by the "more recent of column A, fallback to column B"
If my table looks like this: id, reminder_at, updated_at
1, 01-11-2019, 12-01-2018
2, null, 01-04-2019
3, null, 01-02-2019
4, 01-01-2019, 01-04-2019
expected sorting output would be
4, 01-01-2019, 01-04-2019 # 01-01-2019 is soonest
3, null, 01-02-2019 # then 01-02-2019
2, null, 01-04-2019 # then 01-04-2019
1, 01-11-2019, 12-01-2018 # then 01-11-2019
I'm currently doing this with application code, and i'd prefer to do in SQL
For example if the reminder_at went to NULL for record 1, then it would immediately go to the top because the updated_at date is the oldest
Currently:
SELECT *
FROM "tasks"
WHERE completed_at IS NULL
ORDER by reminder_at, updated_at
EDIT with Correct Answer:
SELECT *
FROM "tasks"
WHERE completed_at IS NULL
ORDER by COALESCE(reminder_at, updated_at)
use coalesce. It chooses the first non null value.
select * from tab
order by coalesce(col1, col2)
if instead, you wanted to use the greater of the 2 dates.. then use greatest()
select * from tab
order by greatest(col1, col2)
I am interpreting your data format to be mm-dd. Should 3 and 2 be flipped in your output, the second coming after the fourth?
Does the following work?
select id,reminder_at,updated_at,greatest(coalesce(reminder_at,'1/1/1900'),coalesce(updated_at,'1/1/1900')) as testcolumn from test order by greatest(coalesce(reminder_at,'1/1/1900'),coalesce(updated_at,'1/1/1900'));
Related
I'm trying to get typeorm to generate a select query with group by clause, in which the parameters of the group by clause references the column in the select clause using its numeric order number:
SELECT SUBSTRING(A, 1, LENGTH(A)), some_expression(B), DISTINCT C
FROM table
GROUP BY 1, 2
Instead of
SELECT SUBSTRING(A, 1, LENGTH(A)), some_expression(B), DISTINCT C
FROM table
GROUP BY SUBSTRING(A, 1, LENGTH(A)), some_expression(B)
Is there an elegant way to do this? I'm using the QueryBuilder API to generate a sql query which is then used for some other purpose.
I have the following code to join two tables microposts and activities with micropost_id column and then order based on created_at of activities table with distinct micropost id.
Micropost.joins("INNER JOIN activities ON
(activities.micropost_id = microposts.id)").
where('activities.user_id= ?',id).order('activities.created_at DESC').
select("DISTINCT (microposts.id), *")
which should return whole micropost columns.This is not working in my developement enviornment.
(PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
If I add activities.created_at in SELECT DISTINCT, I will get repeated micropost ids because the have distinct activities.created_at column. I have done a lot of search to reach here. But the problem always persist because of this postgres condition to avoid random selection.
I want to select based on order of activities.created_at with distinct micropost _id.
Please help..
To start with, we need to quickly cover what SELECT DISTINCT is actually doing. It looks like just a nice keyword to make sure you only get back distinct values, which shouldn't change anything, right? Except as you're finding out, behind the scenes, SELECT DISTINCT is actually acting more like a GROUP BY. If you want to select distinct values of something, you can only order that result set by the same values you're selecting -- otherwise, Postgres doesn't know what to do.
To explain where the ambiguity comes from, consider this simple set of data for your activities:
CREATE TABLE activities (
id INTEGER PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE,
micropost_id INTEGER REFERENCES microposts(id)
);
INSERT INTO activities (id, created_at, micropost_id)
VALUES (1, current_timestamp, 1),
(2, current_timestamp - interval '3 hours', 1),
(3, current_timestamp - interval '2 hours', 2)
You stated in your question that you want "distinct micropost_id" "based on order of activities.created_at". It's easy to order these activities by descending created_at (1, 3, 2), but both 1 and 2 have the same micropost_id of 1. So if you want the query to return just micropost IDs, should it return 1, 2 or 2, 1?
If you can answer the above question, you need to take your logic for doing so and move it into your query. Let's say that, and I think this is pretty likely, you want this to be a list of microposts which were most recently acted on. In that case, you want to sort the microposts in descending order of their most recent activity. Postgres can do that for you, in a number of ways, but the easiest way in my mind is this:
SELECT micropost_id
FROM activities
JOIN microposts ON activities.micropost_id = microposts.id
GROUP BY micropost_id
ORDER BY MAX(activities.created_at) DESC
Note that I've dropped the SELECT DISTINCT bit in favor of using GROUP BY, since Postgres handles them much better. The MAX(activities.created_at) bit tells Postgres to, for each group of activities with the same micropost_id, sort by only the most recent.
You can translate the above to Rails like so:
Micropost.select('microposts.*')
.joins("JOIN activities ON activities.micropost_id = microposts.id")
.where('activities.user_id' => id)
.group('microposts.id')
.order('MAX(activities.created_at) DESC')
Hope this helps! You can play around with this sqlFiddle if you want to understand more about how the query works.
Try the below code
Micropost.select('microposts.*, activities.created_at')
.joins("INNER JOIN activities ON (activities.micropost_id = microposts.id)")
.where('activities.user_id= ?',id)
.order('activities.created_at DESC')
.uniq
I have table with column position, which in some cases, for some collection of records can be nil. I have default order options like
order('positions ASC')
id| name | position
1 5 null
2 6 null
3 7 null
If for some collection that I sort (example above), all values have null in position column, in which order I will get this collection from db?
I'm suggestion I will get collection in order of ids (1,2,3). Am I correct?
Addition #1: DB - Postgresql
According Postgres manual, if no sorting clause the records are returned according with physical position at the disk. It says nothing for sorted records with equal values on sort fields. But, it uses b-tree and, like clasic db managers, it must return on the order stored at the b-tree. You must expect that each of this change on db reorganization.
At the end, there are no warranty on the order of records with same values on sort fields.
Note: using Postgres you can make the NULL values at the first or the last (it is detailed at the referrer link).
At this related question, I'm agree with #macek.
You can do something like this.
Cats:
id| name | position
1 5 null
2 6 null
3 7 not_null
nil = Cat.order("id ASC").where(position: nil) = [1, 2]
not_nil = Cat.order("id ASC").where("position is not null") = [3]
not_nil + nil = [3, 1, 2]
This preserves order.
I am trying a sqlite select query statement as below:
SELECT IndicatorText
FROM Table
where IndicatorID in('13','25','64','52','13','25','328')
AND RubricID in('1','1','1','1','1','1','6')
This gives an output but the duplicate values are not displayed. I want to display all the values of IndicatorText even though it is duplicate.
Please help me with this query.
The two IN conditions are evaluated individually.
To check both values at once, you could concatenate them so that you have a single string to compare:
SELECT IndicatorText
FROM MyTable
WHERE IndicatorID || ',' || RubricID IN (
'13,1', '25,1', '64,1', '52,1', '13,1', '25,1', '328,6')
However, doing this operation on the column values prevents the query optimizer from using indexes, so this query will be slow if the table is big.
To allow optimizations, create a temporary table with the desired values, and join that with the original table:
SELECT IndicatorText
FROM MyTable
NATURAL JOIN (SELECT 13 AS IndicatorID, 1 AS RubricID UNION ALL
SELECT 25, 1 UNION ALL
SELECT 64, 1 UNION ALL
SELECT 52, 1 UNION ALL
SELECT 13, 1 UNION ALL
SELECT 25, 1 UNION ALL
SELECT 328, 6)
I coder for iOS and I use SQLite for my data storage.
For now i have two tables in my database. This is table_1 and table_2 (it's easier for understanding)
About struct:
table_1 contain id field (int type) and some_value field (text type)
table_2 contain id field (int type) and table_1_id field (int type)
My question is next: how to select all row from table_1 via array table_1_id field table_2, and this is must SELECT with ORDER BY. I mean order by array.
For example:
if table_2 -> table_1_id contain value 5, 1, 10, 3, 15, 2
the result of output must be in this order.
For now my query is simple:
SELECT * FROM table_1 WHERE id IN (5, 1, 10, 3, 15, 2)
but the select not return order for this query it return data order by 1, 2, 3, 5, 10, 15.
I think I make relation between my table and make SELECT from table_2 uses ORDER BY, but I don't know how to do this correct.
Thanks in advance!
(Very important for me return this order - 5, 1, 10, 3, 15, 2)
I find some result in stackoverflow
link
This is work for me:
SELECT * FROM "comments" WHERE ("comments"."id" IN (1,3,2,4)) ORDER
BY id=1 DESC, ID=3 DESC, id=2 DESC, ID=4 DESC
This is hard code but I create this query string programmatically in cycle and this work great.