concat all rows in one rows - sql

Hi i need to concat all rows from my table.
I have this query select * from table1; this table contains 400 fields
i cannot do this select column1 ||','||column2||','||.....from table1
can someone help e to fix it using select * from table1 to concatinate all rows.
And thank you.

In Oracle (and similar in other DBMS) you could use system tables.... and do this in two steps:
Assuming you want to combine all the columns into 1 column for X rows...
STEP 1:
SELECT LISTAGG(column_Name, '|| Chr(44)||') --this char(44) adds a comma
within group (order by column_ID) as Fields
--Order by column_Id ensures they are in the same order as defined in db.
FROM all_tab_Cols
WHERE table_name = 'YOURTABLE'
and owner = 'YOUROWNER'
--Perhaps exclude system columns
and Virtual_Column = 'NO'
STEP 2:
Copy the results into a new SQL statement and execute.
The would look something like Field1|| Chr(44)||Field2|| Chr(44)||Field3
SELECT <results>
FROM YOURTABLE;
which would result in a comma separated list of values in 1 column for all rows of YOURTABLE
If the length of all the columns (along with , space and ||) would exceed the 4000 characters allowed... we can use a clob data type instead through the use of XML objects...
* Replace step 1 with *
SELECT RTRIM(XMLAGG(XMLELEMENT(Column_ID,Column_Name,'|| Chr(44)||').extract('//text()') order by Column_ID).GetClobVal(),'|| Chr(44)||') fields
FROM all_tab_Cols
WHERE table_name = 'YOURTABLENAME'
and owner = 'YOUROWNER'
--Perhaps exclude system columns
and Virtual_Column = 'NO';
Syntax for the above attributed to This Oracle thread but updated for your needs.

Related

Required to create an empty table by joining multiple tables in Oracle DB

I got an error while creating an empty table by joining two tables.
I have two tables tab1 & tab2 and there are many common columns names in both tables.
I tried this:
create table tab3 as
select * from tab1 a, tab2 b where a.id = b.id and 1=2;
This gave ORA-00957: duplicate column name. As I mentioned above there are many common columns name between these two tables. If I prepare a create table statement by writing around 500 column names one by one then it will consume lots of time. Please help me out here.
The simple answer is, don't use *. Or is that the whole point, to avoid writing five lines of column names?
One way to avoid these conflicts, but that assumes that you are joining on all columns with the same name in both tables and on no other columns, is to do something like
create table new_table as
select *
from table_a natural join table_b
where null is not null
;
(As you can guess, as an aside, I prefer null is not null to 1 = 2; the parser seems to prefer it too, as it will rewrite 1 = 2 as null is not null anyway.)
Will you need to control the order of the columns in the new table? If you do, you will need to write them out completely in the select clause, regardless of which join syntax you choose to use.
That's an interesting question.
The only idea I have to offer it to let another query to compose the query you need
select 'select ' || listagg(col_name, ', ') within group(order by 1) || 'from tab1 a,tab2 b where (a.id=b.id) and 1=2'
from (select 'a.' || column_name col_name from user_tab_cols where table_name = 'TAB1'
union all
select 'b.' || column_name from user_tab_cols where table_name = 'TAB2')
Please be aware for subqueries you need to specify table names in the upper case

Compare datatype of all the columns of tables with one configuration table in plsql

I have one table CONFIG_PRAM which contains columns like colname , datatype and many more details of existing tables.
Example
CREATE TABLE CONFIG_PRAM
( colname varchar(40),
datatype varchar(40)
);
I have to compare those columns and datatype present in CONFIG_PRAM table with the existing table`s columns.
Example: I have one existing table test1 table in database
create table test1 ( employee_id NUMBER(6),
sal NUMBER(6,8));
And if I found any mismatch I need to update CONFIG_PRAM table with correct data type.
FOR above one in CONFIG_PRAM table we have sal number
but actually it is number(6,8) in table so I have to update CONFIG_PRAM table with exact datatype.
I have tried like this:
select distinct colname , datatype
from CONFIG_PRAM , all_tab_columns
where upper(column_name)=upper(colname )
and data_type=datatype
and table_name in ('TEST1')
But Suppose Table A has Number(6,8)
and CONFIG_PRAM table contain only Number
then it is not giving correct results.
Issue is this query is not comparing decimal values exactly. Can you please provide a solution for this in sql/PLSQL?
This query joins your table to ALL_TAB_COLUMNS on the basis of COLUMN_NAME. This means it only works properly when CONFIG_PRAM has entries for just the one table. Perhaps it needs a column for TABLE_NAME as well?
select cp.colname
, cp.datatype as config_datatype
, atc.data_type as actual_datatype
, atc.data_length as actual_length
, atc.data_precision as actual_precision
, atc.data_scale as actual_scale
from CONFIG_PRAM cp
join all_tab_columns atc
on atc.column_name = cp.colname
where atc.owner = user
and atc.table_name in ('TEST1')
and upper(cp.datatype) != case
when atc.data_type = 'VARCHAR2'
then atc.data_type||'('||atc.data_length||')'
when atc.data_type = 'NUMBER'
and instr(cp.datatype, ',') = 0
and atc.data_scale = 0
then atc.data_type||'('||atc.data_precision||')'
when atc.data_type = 'NUMBER'
then atc.data_type||'('||atc.data_precision||','||atc.data_scale||')'
else atc.data_type
end
;
The WHERE clause compares your datatype column with an assembled datatype string. Obviously there are more potential datatypes than this query handles. You will need to extend it as necessary. Also, variations in the formatting of the datatype string will produce false positives. So you should have a proper think about the structure of your CONFIG_PRAM table: the looser the rules you apply on insert or update the more work you have to do when it comes to selecting it for use.
Here is a SQL Fiddle demo.
ALL_TAB_COLUMNS contains many more columns than just data_type. You will also need to compare at the very least data_length, data_precision and data_scale.
Your join is also missing table_name and owner, and it is better to use ANSI join syntax.

Vertica Dynamic Max Timestamp from all Tables in a Schema

System is HP VERTICA 7.1
I am trying to create a SQL query which will dynamically find all particular tables in a specific schema that have a Timestamp column named DWH_CREATE_TIMESTAMP from system tables. (I have completed this part successfully)
Then, pass this list of tables to an outer query or some kind of looping statement which will select the MAX(DWH_CREATE_TIMESTAMP) and TABLE_NAME from all the tables in the list (200+) and union all the results together into one list.
The expected output is a 2 column table with all said tables with that TS field and the max of each value. Tables are constantly being created and dropped, so the point is to make everything totally dynamic where no TABLE_NAME values are ever hard-coded.
Any idea of Vertica specific ways to accomplish this without UDF's would be greatly appreciated.
Inner Query (working):
select distinct(table_name)
from columns
where column_name = 'DWH_CREATE_TIMESTAMP'
and table_name in (select DISTINCT(table_name) from all_tables where schema_name = 'PTG_DWH')
Outer Query (attempted - not working):
SELECT Max(DWH_CREATE_DATE) from
WITH table_name AS (
select distinct(table_name)
from columns
where column_name = 'DWH_CREATE_DATE' and table_name in (select DISTINCT(table_name) from all_tables where schema_name = 'PTG_DWH'))
SELECT MAX(DWH_CREATE_DATE)
FROM table_name
Thanks!!!
No way to do that in one SQL .
You can used the below method for node max timestamp columns values
select projections.anchor_table_name,vs_ros.colname,max(max_value) from vs_ros,vs_ros_min_max_values,storage_containers,projections where vs_ros.colname ilike 'timestamp'
and vs_ros.salstorageid=storage_containers.sal_storage_id
and vs_ros_min_max_values.rosid=vs_ros.rosid
and storage_containers.projection_name=projections.projection_name
group by projections.anchor_table_name,vs_ros.colname

PostgreSQL: change order of columns in query

I have a huge query with about 30 columns.
I ordered the query with:
Select *
From
.
.
.
order by id,status
Now I want that in the result to present columns in certain way.
The id column will be first, followed by status column and then all the rest.
is there a way to do that (without manually specifying 30 column names in select). Something like: Select id,status, REST
this will give you all columns except those you don't want to
SELECT id, status,' || array_to_string(ARRAY(SELECT 'o' || '.' || c.column_name
FROM information_schema.columns As c
WHERE table_name = 'table_name'
AND c.column_name NOT IN('id', 'status')
), ',') || ' FROM officepark As o' As sqlstmt
The "select *" will return the fields in the order in which they were listed when the table was created. If you want them returned in a particular order, just be sure to create the table with that order.
If you have to do it repeatly, you could create a new table:
CREATE TABLE FOO as
SELECT id, status, mydesiredorder
Or just a view,don't forget to move index constraint and foreign keys. If you must do it just once, was faster specify 30 columns than ask here

Selecting multiple columns in SQL

I have a table with over a hundred columns, but I only want to select the the columns named nvarchar1, nvarchar2, ... nvarchar64. All of these 64 columns are next to each other so I was thinking maybe there is a way to select using column indices, but I couldn't find a solution.
Note: I don't want to do the obvious solution,
SELECT nvarchar1,
nvarchar2,
...
nvarchar64
...
Make use of the result from this query:
select column_name + ','
from information_schema.columns
where table_name = 'your table name'
and column_name like 'nvarchar%'