I have a query -
select whereto, id from table where id=1;
I need to find the position of where in this query. It should not consider the column whereto.
How we can achieve it in postgres?
I could try this on psql on Mac Big Sur.
postgres=# \set myvar 'select whereto, id from table where id=1;';
And if I try where (with a space), it gives me -
postgres=# select strpos(:'myvar','where ');
strpos
--------
31
(1 row)
As per the documentation, strpos takes only string and not regex. - https://www.postgresql.org/docs/current/functions-string.html
Related
The query:
select ;
is valid in postgresql. It returns a tuple with no attribute.
# select ;
--
(1 row)
It has clear semantics and the result can be used as a subquery:
# select 1 from (select ) as rip;
?column?
----------
1
(1 row)
In fact, one can create a table with no attributes using it. One can even add tuples to it!!
But my question is, why does it exist?
I see value in a select without a from clause, as psql can be used as a calculator:
# select 3 * 6;
?column?
----------
18
(1 row)
and or be used to call a UDF.
But I can not envision a use for select ;
it is useful or is it an oddity of postgresql's parser?
See here:
https://www.postgresql.org/docs/current/sql-select.html
Empty SELECT Lists
The list of output expressions after SELECT can be empty, producing a zero-column result table. This is not valid syntax according to the SQL standard. PostgreSQL allows it to be consistent with allowing zero-column tables. However, an empty list is not allowed when DISTINCT is used.
I can alias a table name in a Postgres statement like this:
SELECT a.id FROM very_long_table_name AS a;
Is there a mechanism to set up a similar alias that persists for a psql session?
For example:
$: psql -d sample
sample=# CREATE ALIAS a for very_long_table_name;
sample=# select id from a limit 1;
id
____
1
As shown in the manual this can be done using psql variables:
sample=# \set a 'very_long_table_name'
sample=# select id from :a limit 1;
id
----
1
(1 row)
If you don't want to run \set every time manually, you can include your common short names in ~/.psqlrc which is read when you start psql
I don't know of a way to create such an alias, but you may create a view on top of your table, and give it a short name, e.g.
CREATE VIEW short_name AS
SELECT *
FROM very_long_table_name;
Then, use the view name as you would the alias. Since views generally perform as well as the underlying tables, with regard to indices, you should not lose much in terms of performance.
I think the best option is to create a temporary view.
This solution is not restricted to psql.
CREATE TABLE averylongname (id integer PRIMARY KEY);
INSERT INTO averylongname VALUES (1);
CREATE TEMPORARY VIEW x AS SELECT * FROM averylongname;
The view will automatically vanish when your database session ends, and it can be used with DML statements as well:
INSERT INTO x VALUES (2);
SELECT * FROM x;
id
----
1
2
(2 rows)
I need to lowercase array content in PostgreSQL, lower(array['array_content'])) or array[lower('array_content'])) does not work. Actual array is much, much longer.
SELECT * FROM kliendi_aadress WHERE lower(linn) LIKE ANY (array['Tallinn', 'Tartu','Narva'])
Can this even be done?
Well ILIKE solved this problem for me
SELECT * FROM kliendi_aadress WHERE linn ILIKE ANY (array['Tallinn', 'Tartu','Narva']);
the first that come to mind is ugly:
db=# select lower(array['Tallinn', 'Tartu','Narva']::text)::text[];
lower
-----------------------
{tallinn,tartu,narva}
(1 row)
Here I lower text representation of your array and then cast it back to array.
And so comparison:
db=# select 'tartu' = any (lower(array['Tallinn', 'Tartu','Narva']::text)::text[]);
?column?
----------
t
(1 row)
The citext extension can come in handy in this situation.
-- If you haven't enabled citext in your DB
CREATE EXTENSION citext;
select 'tartu' = any (array['Tallinn', 'Tartu','Narva']::citext[])
should work.
Fresh postgres installation, db 'test', table 'Graeber' created from another program.
I want to see the content of table 'Graeber'. When I connect to the database and try to select the content of 'Graeber', the application tells me : ERROR: relation "graeber" does not exist.
See screenshot:
What is wrong here?
Try adding the schema as in:
select *
from public.Graeber
If that doesn't work, then it is because you have a capital letter so try:
select *
from public."Graeber"
Hope this helps.
When using the psql console in cmd, sometimes you may forget to add ';' at the end of select statement
Example -1: select * from user #does not give any result back
select * from user; #this works with ';' at the end
Don't take me wrong I faced this issue in Postgresql version 13
See This Example.
queuerecords=# create table employee(id int,name varchar(100));
CREATE TABLE
queuerecords=# insert into employee values(1,'UsmanYaqoob');
INSERT 0 1
queuerecords=# select * from employee;
id | name
----+-------------
1 | UsmanYaqoob
(1 row)
In Postgresql 8 why this is ok
select * from prod where code like '1%'
select * from prod where code like '%1'
but this returns 0 rows (there are codes begining/ending with digit 1)
select * from prod where code like '1%1'
Update
That happens in my current instalation:
# psql --version
psql (PostgreSQL) 8.3.7
create table a(code char(10));
CREATE TABLE
db=# insert into a values('111');
INSERT 0 1
db=# select * from a where code like '1%';
code
------------
111
(1 row)
db=# select * from a where code like '%1';
code
------
(0 rows)
db=# select * from a where code like '1%1';
code
------
(0 rows)
Update 2
It is the datatype ! With varchar it is Ok !
Thank you.
Is it because the datatype is char(10)?
This means that it will always occupy 10 characters even though you just insert something shorter like "111". Therefore, if you don't use a 10-characters string with "1" at the end, "%1" and "1%1" will never match.
(EDIT: I had posted the following (with with an AND operator, rather than OR).
SELECT * FROM prod WHERE code LIKE '%1' OR code LIKE '1%';
If you want AND operator, the query in the question should work OK. However, if you want to use OR operator, then my above query is probably one of the better ways of doing it.