Hi Postgres community :D
I am trying to read contents of tables to grasp the picture of them.
So, my question is:
How could it be done to display all the head of tables inside a database giving same result as below naive tidious queries.
I guess there must be a fancy way of just one line query to do this..
Please help me out!
# naive
SELECT * FROM mytable0001;
SELECT * FROM mytable0002;
SELECT * FROM mytable0003;
...
SELECT * FROM mytable9999;
# wannabe
SELECT * FROM foo (SELECT table_name FROM information_schema.tables) AS foo limit 5;
Thank you in advance!
You can try to use psql CLI and \gexec command.
With following input:
select format('select * from %s;',tablename)
from pg_tables
where tablename like 'table%'
\gexec
You get in one go:
select format('select * from %s;',tablename)
from pg_tables
where tablename like 'table%'
select * from table0001;
c1 | c2
----+---------
1 | table 1
(1 row)
select * from table0002;
c1 | c2
----+---------
1 | table 2
2 | table 2
(2 rows)
select * from table0003;
c1 | c2
----+---------
1 | table 3
2 | table 3
3 | table 3
(3 rows)
Related
Suppose I have a PostgreSQL function that takes 2 parameters: id (INT), email (TEXT) and can be called like this:
SELECT * FROM my_function(101, 'myemail#gmail.com')
I want to run a SELECT query from a table that would return multiple id's:
SELECT id FROM mytable
| id |
--+------+
| 101 |
--+------+
| 102 |
--+------+
| 103 |
How would I loop through and plug each of the returned id's into my function in a query. FOr this example just assume the default email is alwasy "myemail#gmail.com"
I'm on mobile so I can't test it, but I think maybe this will work.
SELECT * FROM (select my_function(id, 'myemail#gmail.com') from mytable);
You can use a cross join:
SELECT *
FROM my_table mt
cross join lateral my_function(mt.id, 'myemail#gmail.com') as mf
Just as in oracle database we have column_id in all_tabs_columns is there a similar field for postgresql?
For example if in oracle we can order by column id by selecting from columns do we have a similar query in pgsql ?
The column attnum in pg_attribute shows the order of a column in a table.
yes, you can also order by column number in Postgres:
with sampledata(a,b) as (values (1,'z'),(2,'y'),(3,'x'))
SELECT a,b
FROM sampledata
ORDER BY 1;
a | b
---+---
1 | z
2 | y
3 | x
(3 rows)
with sampledata(a,b) as (values (1,'z'),(2,'y'),(3,'x'))
SELECT a,b
FROM sampledata
ORDER BY 2;
a | b
---+---
3 | x
2 | y
1 | z
(3 rows)
The closest equivalent to all_tab_columns is information_schema.columns
So you are probably looking for something along the lines:
select column_name
from information_schema.columns
where table_name = '...'
order by ordinal_position;
In postgresql. Let's say you have a table with the name Table with the following columns:
Col 1,
Col 2,
Col 3
You can completely reorder the columns in postgresql by writing the query
SELECT
Col 3,
Col 2,
Col 1
FROM
Table
I'm trying to get the average of words based on each message.body count of words from messages table
an example of that would be
**message.body**
-------------------
-->"aaz aae aar"
-->"aaz"
-->"aaz aae"
Output must be: AVG( 3 + 1 + 2 ) = 2
For that I've been applying the following query
SELECT AVG(temp.words) FROM (SELECT (array_length(string_to_array(messages.body,' '),1)) AS words FROM messages) AS temp
message.body is just text.
Any help will be appreciated.
giving the result you expect:
t=# with messages(body) as (values('aaz aae aar'),('aaz'),('aaz aae')) SELECT AVG(temp.words) FROM (SELECT (array_length(string_to_array(messages.body,' '),1)) AS words FROM messages) AS temp;
avg
--------------------
2.0000000000000000
(1 row)
t=# with messages(body) as (values('aaz aae aar'),('aaz'),('aaz aae')) SELECT *FROM (SELECT (array_length(string_to_array(messages.body,' '),1)) AS words,messages.body FROM messages) AS temp;
words | body
-------+-------------
3 | aaz aae aar
1 | aaz
2 | aaz aae
(3 rows)
I'm answering my question:
it happens that average function in postgres only accepts Floats as an argument, for that someone needs to cast the input before. Like this:
SELECT(AVG (temporary_.words)) AS average_amount FROM (SELECT CAST(array_length(string_to_array(messages.body,' '),1) AS FLOAT) AS words FROM messages WHERE body!='' ) AS temporary_
I have a table with at least a "name" column and an "ordinal_position" column. I wish to loop each row starting from a certain row the user inputs. Let's say the user inputs "John", and that his ordinal_position is 6 (out of a 10 total). How do I loop only the last 4 rows without using a subquery? I've tried using the "OVER()" window function but it doesn't seem to work on the offset part of the query, and that same offset only takes numbers (as far as I know) not strings.
EDIT (in response to klin):
INSERT INTO foo(id,name,ordinal_position) VALUES
(DEFAULT,'Peter',1),
(DEFAULT,'James',2),
(DEFAULT,'Freddy',3),
(DEFAULT,'Mark',4),
(DEFAULT,'Jack',5),
(DEFAULT,'John',6),
(DEFAULT,'Will',7),
(DEFAULT,'Robert',8),
(DEFAULT,'Dave',9),
(DEFAULT,'Michael',10);
so in my FOR, since the user inputed "John" I want to loop through Will-Michael. Something like the following but without a subquery:
SELECT * FROM foo ORDER BY ordinal_position OFFSET
(SELECT ordinal_position FROM foo WHERE name='John');
Unfortunately, you have to query the table to find an ordinal_position for a given name.
However, do not use offset. You can do it in where clause, for large tables it will be much faster:
select *
from foo
where ordinal_position > (select ordinal_position from foo where name = 'John')
order by ordinal_position;
id | name | ordinal_position
----+---------+------------------
7 | Will | 7
8 | Robert | 8
9 | Dave | 9
10 | Michael | 10
(4 rows)
I am kind of new to mySQL:s union functions, at least when doing inserts with them. I have gotten the following to work based upon a example found on the net:
INSERT INTO tableOne(a, b)
SELECT a, $var FROM tableOne
WHERE b = $var2
UNION ALL SELECT $var,$var
Ok, nothing strange about that. But what happens when I want to insert a third value into the database that has nothing to do with the logic of the Select being done?
Like : INSERT INTO tableOne(a, b, c )
How could that be done?
You can "select" literal values too:
mysql> select 'hello', 1;
+-------+---+
| hello | 1 |
+-------+---+
| hello | 1 |
+-------+---+
1 row in set (0.00 sec)
Hence, you can also use that in INSERT INTO ... SELECT FROM and UNIONs.
INSERT INTO someTable (a, b, c) VALUES
SELECT id, name, 5
FROM someOtherTable
UNION
SELECT id, alias, 8
FROM anotherTable