parameterize asc vs desc sort in postgres sql - postgresql

I want to allow sort to parameterized in a query, field id and order
so I have select .... order by #sortcol
then what? How to I use a parameter to indicate asc vs desc?
Using c# npgsql library.

Related

Cannot create materialized view with ORDER BY clause in TimescaleDb 2.7.0

The timescale docs seem to suggest that since 2.7.0 it should be possible to make materialized views which include an order by clause. (See "timescale.finalized" option here and "function support" here).
However, I have not been able to get this to work for me. When I try to create my materialized view I get:
ERROR: invalid continuous aggregate query
DETAIL: ORDER BY is not supported in queries defining continuous aggregates.
HINT: Use ORDER BY clauses in SELECTS from the continuous aggregate view instead.
Is there something fundamental I'm misunderstanding about how this should work?
Here is the full script:
> select extname, extversion from pg_extension where extname = 'timescaledb';
extname | extversion
-------------+------------
timescaledb | 2.7.0
(1 row)
> CREATE TABLE stocks_real_time (
time TIMESTAMPTZ NOT NULL,
price DOUBLE PRECISION NULL
);
CREATE TABLE
> SELECT create_hypertable('stocks_real_time','time');
create_hypertable
-------------------------------
(7,public,stocks_real_time,t)
(1 row)
> CREATE MATERIALIZED VIEW mat_view_stocks_real_time
WITH (timescaledb.continuous)
AS (
SELECT
time_bucket('60 minutes', time) as bucketed_time,
AVG(price) as price
FROM stocks_real_time
GROUP BY bucketed_time
ORDER BY bucketed_time
);
ERROR: invalid continuous aggregate query
DETAIL: ORDER BY is not supported in queries defining continuous aggregates.
HINT: Use ORDER BY clauses in SELECTS from the continuous aggregate view instead.
I still get the same error if I explicitly add "timescaledb.finalized=true" to the with clause.
(NB: I work at Timescale!)
We have an open issue to support this, and I think the confusion is because we now support aggregates with order by clauses in them, this means things like: SELECT percentile_cont(price) WITHIN GROUP (ORDER BY time) or SELECT array_agg(foo ORDER BY time)
So I think that is probably where the confusion is coming from, but like I said, we have an open issue to support that sort of order by. You can also apply the order by in the SELECT from the continuous aggregate though: ie SELECT * FROM mat_view_stocks_real_time ORDER BY bucketed_time and that should work just fine.

SQL and optional sorting ASC / DESC

I know how to add an optional parameters to an sql query
it is done like this
select * from test t where (?1 is null or t.myColumn = ?1)
where ?1 is a parameter which you can pass from language
such as java (i.e using named queries), the advantage is that I don't
need to use ORM nor I need manually build (concatenate) strings into
query.
is there anything similar to make ASC and DESC optional?
No, you will have to use dynamic SQL (statements constructed on the fly) for that.
There is a trick you could use for numeric columns:
... ORDER BY col * CASE WHEN $1 = 'DESC' THEN -1 ELSE 1 END

Retrieve Case Insensitive SQL Select Query using DB2

Below sql select query retrieves the data from table.
SELECT DISTINCT FRUIT_NAME,FRUIT_ID FROM Fruits ORDER BY FRUIT_NAME ASC
I have used "ORDER BY FRUIT_NAME ASC" which fetches the results based on Assending order as shown below.
Results :
Apple
Bannana
Mango
apricots
blueberries
I want a case insensitive search results like below.
Apple
apricots
Bannana
blueberries
Mango
I dont want to use upper() or lower() as it might affect performance for larger table data.
Also COLLATE NOCASE doesn't work with db2. Below is the error i got when i used
COLLATE NOCASE in select sql query in db2.
1) [Code: -104, SQL State: 42601] ILLEGAL SYMBOL "COLLATE".
Is there any way to retrieve case insensitive data from sql select query using db2?
You could order using the LOWER function:
SELECT DISTINCT FRUIT_NAME, FRUIT_ID
FROM Fruits
ORDER BY LOWER(FRUIT_NAME);
Of course, this means the ORDER BY step can't use an index. If you need to order rapidly regardless of case, you could consider storing an all-lowercase version of the column, as one option.

JPA 1: JPQL for ORDER BY NULLS LAST

Is there a way to do an ordering in JPQL query like:
SELECT v
FROM Vehicle v
WHERE ...
ORDER BY v.lastUserUpdate DESC NULLS LAST, v.id DESC;
The NULLS LAST breaks the query. Is there a correct way to do this?
I don't know a JPQL function to allow this as I believe it is database specific. JPA 2.0 has a 'SQL' key word that you can use to have "nulls last" passed through. Something like
"ORDER BY v.lastUserUpdate DESC SQL('NULLS LAST'), ..."
See
http://java-persistence-performance.blogspot.ca/2012/05/jpql-vs-sql-have-both-with-eclipselink.html for more details on what is available in JPA and eclipselink. TopLink uses EclipsLink for JPA, so you will have to verify the version you are using and use native TopLink API if it doesn't support it and you can't upgrade.

Proper GROUP BY syntax

I'm fairly proficient in mySQL and MSSQL, but I'm just getting started with postgres. I'm sure this is a simple issue, so to be brief:
SQL error:
ERROR: column "incidents.open_date" must appear in the GROUP BY clause or be used in an aggregate function
In statement:
SELECT date(open_date), COUNT(*)
FROM incidents
GROUP BY 1
ORDER BY open_date
The type for open_date is timestamp with time zone, and I get the same results if I use GROUP BY date(open_date).
I've tried going over the postgres docs and some examples online, but everything seems to indicate that this should be valid.
The problem is with the unadorned open_date in the ORDER BY clause.
This should do it:
SELECT date(open_date), COUNT(*)
FROM incidents
GROUP BY date(open_date)
ORDER BY date(open_date);
This would also work (though I prefer not to use integers to refer to columns for maintenance reasons):
SELECT date(open_date), COUNT(*)
FROM incidents
GROUP BY 1
ORDER BY 1;
"open_date" is not in your select list, "date(open_date)" is.
Either of these will work:
order by date(open_date)
order by 1
You can also name your columns in the select statement, and then refer to that alias:
select date(open_date) "alias" ... order by alias
Some databases require the keyword, AS, before the alias in your select.