using SELECT INTO with multiple rows - sql

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

Related

How to define and reuse list of columns in PostgreSQL

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;

Selecting distinct values within a a group

I want to select distinct values of one variable within a group defined by another variable. What is the easiest way?
My first thought was to combine group by and distinct but it does not work. I tried something like:
select distinct col2, col1 from myTable
group by col1
I have looked at this one here but can't seem to solve my problem
Using DISTINCT along with GROUP BY in SQL Server_
Table example
If your requirement is to pick distinct combinations if col1 and COL2 then no need to group by just use
SELECT DISTINCT COL1, COL2 FROM TABLE1;
But if you want to group by then automatically one record per group is displayed by then you have to use aggregate function of one of the columns i.e.
SELECT COL1, COUNT(COL2)
FROM TABLE1 GROUP BY COL1;
no need group by just use distinct
select distinct col2, col1 from myTable
create table t as
with inputs(val, id) as
(
select 'A', 1 from dual union all
select 'A', 1 from dual union all
select 'A', 2 from dual union all
select 'B', 1 from dual union all
select 'B', 2 from dual union all
select 'C', 3 from dual
)
select * from inputs;
The above creates your table and the below is the solution (12c and later):
select * from t
match_recognize
(
partition by val
order by id
all rows per match
pattern ( a {- b* -} )
define b as val = a.val and id = a.id
);
Output:
Regards,
Ranagal

select same records multiple times with one column value changed in SQL

I have getting same records multiple times with one column value changed using union like this.
Select col1, col2, 'A' as col3
Union
Select col1, col2, 'B' as col3
Union
Select col1, col2, 'C' as col3
I want to know if there is any way to do this in single query instead of writing 3 queries. Can someone please help?
I simple CROSS JOIN with the specified VALUES should do the trick
Select Col1,Col2,Col3
From YourTable A
Cross Join (Values ('A'),('B'),('C') ) B (Col3)
SELECT d.name, x.field1
FROM sys.databases d
, (VALUES('A'), ('B'), ('C')) AS x(field1)
You should look up the cross join syntax but this is an example off how to do it.

SELECT ALL with SUM(Col)

Is there a way to Select all and also get the sum of a column all in the same query?
SELECT *, SUM(Colname) FROM `Table`...
Thank you.
This can easily be done using a window function:
select t.*,
sum(some_value) over () as total_sum
from some_table as t;
This is standard SQL and works on all modern DBMS.
SQLFiddle: http://sqlfiddle.com/#!15/c1a74/1
No, if you want to use aggregate functions then you have to GROUP BY and end up getting a single row for the columns you have specified in that GROUP BY col1, col2, col3.
If you want multiple records (SELECT *) and also want the SUM(Colname) of one of them then do it in 2 separate queries.
Yes you can do that with a subquery
SELECT
*
FROM
Table,
(SELECT
SUM(Colname) SumColumn
FROM
Table) t1
I tested in SQL Server with this small example
CREATE TABLE #Test (IntData INT, Data NVARCHAR(20))
INSERT INTO #Test(IntData, Data)
SELECT 1, 'Data1' UNION
SELECT 3, 'Data2' UNION
SELECT 5, 'Data3' UNION
SELECT 7, 'Data4' UNION
SELECT 9, 'Data5' UNION
SELECT 11, 'Data6'
SELECT
*
FROM
#Test,
(SELECT
SUM(IntData) SumIntData
FROM
#Test) t1
DROP TABLE #Test
Hope this helps

Using Union with Insert to add one row

I have a query which is made up of two select statements with a union in the middle.
This works for what I need it for.
However, there is one value missing which I want to manually enter.
What I'm looking to is:
select * from tab1
union
select * from tab2
union
insert values('John',cast('2013-01-01' as date), 'Jim', 130)
Unfortunately this is not working. Can someone suggest how I do this please?
I'm using Teradata.
You need to keep selecting:
select * from tab1
union
select * from tab2
union
select 'John', cast('2013-01-01' as date), 'Jim', 130 from dual
The name dual is used in Oracle for a table with one row (and one column). Depending on the DBMS you use, you may be able to omit that final FROM altogether (and you may be able to do this in Oracle too):
select * from tab1
union
select * from tab2
union
select 'John', cast('2013-01-01' as date), 'Jim', 130
or you may have to choose from a system catalog table and ensure you get one row returned (FROM systables WHERE tabid = 1 was the classic mechanism in Informix, though you could also use 'sysmaster':sysdual instead of dual, etc, too), or you can select from any other table with a query that is guaranteed one row. There are probably ways to do it using a VALUES clause too.
Note the change from double quotes to single quotes. In strict standard SQL, double quotes enclose a delimited identifier, but single quotes surround strings.
From your question I' guessing you just want to SELECT that row, not INSERT it (into the database):
select * from tab1
union
select * from tab2
union
select "John", cast('2013-01-01' as date), "Jim", 130
You just want to SELECT the data, not INSERT it.
Not very familiar with TeraData, perhaps you need a FROM in which case limiting to 1 record would also make sense:
select * from tab1
union
select * from tab2
union
SELECT 'John',cast('2013-01-01' as date), 'Jim', '130' FROM dbc.columns 1
I am affraid the union must reference a table and if you need to add the data that does not exist in your database, try this:
select * from tab1
union
select * from tab2
union
select * from (SELECT 'John' as col1 ,cast('2013-01-01' as date) as col2, 'Jim' as col3, '130' as col4) dummy
You will, of course, have to change the name of the columns to fit those from your db (i.e. dont use col1, col2 etc.).
Good luck!