How to define and reuse list of columns in PostgreSQL - sql

As the title says it, I have a huge table with a lot of columns, I need only like half or more of them (this is not the point). The point is I don't want to use * because I am getting too many and is taking a little more time than wanted.
I want to basically write a few UNION and writing all columns every time is taking a lot of space and looks messy. Instead what I am looking for is to declare a list of column names and simply reuse it in each SELECT statement if this is possible.
SELECT col1, col2, ... col_n FROM mytbl
UNION
SELECT col1, col2, ... col_n FROM mytbl
UNION
SELECT col1, col2, ... col_n FROM mytbl
UNION
SELECT col1, col2, ... col_n FROM mytbl
I want to get something like
columns_to_extract = [col1, col2, ... col_n]
SELECT columns_to_extract FROM mytbl
UNION
SELECT columns_to_extract FROM mytbl
UNION
SELECT columns_to_extract FROM mytbl
UNION
SELECT columns_to_extract FROM mytbl

Use some client-specific feature for that.
For example for psql client:
\set foobar 'aid, bid'
select :foobar from pgbench_accounts
union all
select :foobar from pgbench_accounts;

Related

SQL - Transposing rows from some columns in a table to each record in thesame table

I am using a platform which accepts minimal SQL functions to write a SQL code. The UNPIVOT function cannot be used on the platform so I have to do this manually. I am thinking along the line of UNION ALL and then CROSS JOINING (which I attempted but ended up with the wrong record counts. Please see image attached.
Any help / pointer will be highly appreciated!
I don't know how you used UNION ALL but it can be done like this:
select col1, col2, col3 as NewCol from Table1
union all
select col1, col2, col4 from Table1
You could also use an ORDER BY clause, so that rows with the same col1 and col2 appear in subsequent rows:
select col1, col2, NewCol
from (
select col1, col2, col3 as NewCol, 1 as ord from Table1
union all
select col1, col2, col4, 2 from Table1
) t
order by col1, col2, ord
A portable approach uses union all:
select col1, col2, col3 as newcol from mytable
union all
select col1, col2, col4 from mytable
If your database supports lateral joins (also called cross apply in some databases) and values(), this can be simplified:
select t.col1, t.col2, x.newcol
from mytable t
cross join lateral (values(col3), (col4)) x(newcol)
You can use a cross join, but it requires some case logic. The exact syntax depends on the database, but something like this:
select t.col1, t.col2,
(case when n.n = 1 then t.col3 else t.col4 end) as newcol
from t cross join
(select 1 as n union all select 2) n;
To load another table, you would do one of the following:
insert these results into a table that has already been created.
Use select into or create table as depending on the database.
If you care about the ordering, then you can add order by t.col1, t.col2, n.n.
In most cases, a simple union all approach is fine (such as GMB suggests). That approach requires scanning the table twice, which incurs some additional overhead. However, if the "table" is really a complex query or view, then only processing it once is a bigger advantage.

Someone knows how to union two or more materialized views in sql?

select *
from
(materialized_v1
union all
materialized_v2);
You need to select, then union. There is nothing specific about materialized view here:
select * from materialized_v1
union all
select * from materialized_v2;
For this to work both views to have the same number of columns, with the same datatypes. It is far better to enumerate the columns in the select clauses, which gives you a chance to adjust the columns and datatypes if needed:
select col1, col2, col3 from materialized_v1
union all
select col4, col4, col5 from materialized_v2;

SELECT INTO with HSQLDB

I am trying to create a new table from the result of a select. This works fine with SQL Server:
SELECT * INTO newTable FROM (SELECT col1, col2, col3 FROM oldTable) x;
Now, I want to achieve the exact same thing with HSQLDB (Version 2.2). I have tried several forms like
SELECT * INTO newTable FROM (SELECT col1, col2, col3 FROM oldTable);
SELECT INTO newTable FROM SELECT col1, col2, col3 FROM oldTable;
CREATE TABLE newTable AS SELECT col1, col2, col3 FROM oldTable;
All these variants result in some form of syntax error. How can I create a table from a select with HSQLDB?
The manual has an example for this:
CREATE TABLE t (a, b, c) AS (SELECT * FROM atable) WITH DATA
HSQLDB requires parentheses around the select (unlike all other DBMS) and it also requires the WITH DATA clause
Ok I found very easier way to do this.
select * into t_bckp FROM t;
Its interesting.

using SELECT INTO with multiple rows

This is re
I want to create a table using the results of a query by utilizing SELECT INTO.
The syntax
SELECT *
INTO Persons_Backup
FROM Persons
is very close to what I want to achieve, with the difference being that I want the FROM to use a query as source.
My situation is a bit more complicated than these simple examples.
I need to create a table and insert multiple rows at the same time. If I could (I can't) use a previously created table the statement would look like this:
INSERT INTO Person_Backup12 (Col1, Col2, Col3)
Select 1, 'a','2001-01-01 12:00'
UNION ALL
Select 83, 'z','2011-09-30 13:27'
UNION ALL
Select 777, 'k','1997-04-25 09:27'
Can I do that while creating a table at the same time?
You can put your query into a common table expression or derived table then SELECT ... INTO from that.
;WITH cte (Col1, Col2, Col3) AS
(
Select 1, 'a','2001-01-01 12:00'
UNION ALL
Select 83, 'z','2011-09-30 13:27'
UNION ALL
Select 777, 'k','1997-04-25 09:27'
)
SELECT *
INTO NewTable
FROM cte
In this case you would probably need some explicit casts to get the desired column datatype (datetime rather than char etc.)
A CTE shouldn't be necessary:
Select 1 as 'Col1', 'a' as 'Col2','2001-01-01 12:00' as 'Col3'
INTO Person_Backup12
UNION ALL
Select 83, 'z','2011-09-30 13:27'
UNION ALL
Select 777, 'k','1997-04-25 09:27'
Worked fine for me in 2008 r2.
It is possible, yes:
SELECT *
INTO Persons_Backup
FROM
(
Select 1 AS Col1, 'a' AS Col2,'2001-01-01 12:00' AS Col3
UNION ALL
Select 83 AS Col1, 'z' AS Col2,'2011-09-30 13:27' AS Col3
UNION ALL
Select 777 AS Col1, 'k' AS Col2,'1997-04-25 09:27' AS Col3
) AS SomeQuery

query multiple tables and combine results into one return table for stored procedure?

I have several different tables, but they all have 2 columns that are the same name. I want to write a stored procedure that searches one column in all of the tables and returns the result. Ideas? I'm fairly nub when it comes to SQL.
The operation you are looking for is UNION or UNION ALL.
SELECT * FROM (
SELECT col1, col2 FROM table1
UNION ALL
SELECT col1, col2 FROM table2
UNION ALL
SELECT col1, col2 FROM table3
) all_tables
WHERE all_tables.col1 = 'something'
If you use UNION rather than UNION ALL, the database will eliminate duplicate rows that may be in multiple tables. If you know there won't be any duplicates, use UNION ALL since it is generally much faster.
Select myColumn FROM Table1
UNION Select myColumn FROM Table2
UNION Select myColumn FROM Table3
..etc
-- Note all column names have to be the same and have to be in each table for this to work
You wouldn't even need a stored procedure...just use a union query.
select field1, field2 from table1 where table1.field1=criteria
union
select field1, field2 from table2 where table2.field1=criteria
union
select field1, field2 from table3 where table3.field1=criteria
etc...