sum of all columns in sql - sql

sum of all columns in sql
i have 48 columns with 40,000 rows.
I want a new row which is sum of all columns.
I know I can do:
select sum(a), sum(b), sum(c) .....but i have to type that 48 times.
Is there a better way ?
the column has int values. And also has a lot of 0's

This problem smacks of poor design, you should fix your structure, most likely each of your 48 column names could be a value in a single column next to the column you're aggregating (or another table altogether).
Then you'd have a simple query like below that returns 48 rows:
SELECT col1,SUM(col2)
FROM YourTable
GROUP BY col1
Fixing the structure is ideal, but you can get what you're after using system views:
SELECT ',SUM('+c.name+')'
FROM sys.tables t
JOIN sys.columns c
ON t.object_id = c.object_id
WHERE t.name = 'YourTable'
You could make it dynamic so you can execute it all at once, but if you're just looking for a quick way to save some keystrokes that will work.

Actually, you are not forced to use sum 48 times.
You can retrieve all the column names querying the information_schema. Then loop over all these columns and execute the query.
This query would return the column_names of your table :
select column_name
from information_schema.columns
where table_name = 'yourTable'
and table_schema = 'yourSchema'
Then you just need to loop over each column_name and execute the query as a string using sp_executesql. Simply set the column name in the string the value of the current iteration in the loop.
If you want all the columns returned in one time, you can use union.
I think you have all what is needed here to accomplish what you want.

Related

Postgres SQL Statments, getting the right data

I know Postgres has a lot of functions, and I'm not the fittest in SQL anyways, but I need to know if its possible with Postgres to somehow get the data in a table with that statement-
SELECT table_name
FROM information_schema.tables
where table_schema='public'
I'm getting my tables I created which I want.
eg.
table_name
myTable1
myTable2
myTable3
Each of the Tables has different data filled, but every table has a column version and I want to access it.
Joining the tables wouldn't work at least it didn't went out the way I wanted. What I want is this
table_name
Version
myTable1
21
mytABLE2
12
with
Select version from mytable1 order by version desc limit 1
I get the last version but I would like to combine this somehow
I mean I can join the 3 tables but that's not what I want
So my question is it possible to do it? Or do I have to work around.
Because I believe that getting the table names is on a higher layer
In the end you need dynamic SQL for this. One way to do it, is to use a PL/pgSQL function, another way is to use query_to_xml() to run a dynamic query without the use of PL/pgSQL.
with data as (
select query_to_xml(format('select version
from %I.%I
order by version desc limit 1',
t.table_schema, t.table_name),
true, true, '') as result
from information_schema.tables t
where t.table_schema = 'public'
)
select (xpath('/row/version/text()', result))[1]::text::int as version
from data;
The format() function is used to build a SELECT query the way you need it. The query_to_xml() will then return something like:
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<version>21</version>
</row>
The xpath() function is then used to extract the 21 from that XML. As it returns an array of matches, the [1] is used to extract the first match. This is then converted to an integer.
Note that if there is at least one table that does not contain a column named version this query will fail. You can work around that by extending the WHERE clause to:
where table_schema = 'public'
and exists (select *
from information_schema.columns c
where c.table_schema = t.table_schema
and c.table_name = t.table_name
and c.column_name = 'version'

How to get several records searching on the whole database

My question is, is it possible to list all the columns from the whole database not just in specific tables based on 3 different criteria which ones are in an "OR" relationship. so for example I have database called "Bank" and I have 3 criterias "Criteria1; Criteria2; Criteria3" and if any of them is true so the relation between them should be OR and not AND than I will get back all the columns matching the criterias and the output put should provide "account_id" or "customer_id" from the same table.
How do I procced in this case?
It is possible, but you probably don't want to do it. Anyway, you could write a stored procedure that finds all tables that contain the columns you want:
select distinct table_name from user_tab_cols utc
where exists (select * from user_tab_cols where table_name = utc.table_name
and column_name = 'ACCOUNT_ID')
and exists (select * from user_tab_cols where table_name = utc.table_name
and column_name = 'CUSTOMER_ID');
Given the tables you could run a query where you append table name and your criteria:
execute immediate 'select account_id, customer_id from agreement where '
|| your_criteria_here;
A bit messy, inefficient and treat this as pseudo-code. However, if you really want to do this for an ad-hoq query it should point you in the right direction!

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

How to determine the number of "Column Name" in a table?

I have a table tblEmployeeInfowhich has atleast a 100+ column name.
I want to know how many column name are in that table. Is that possible?
NOTE:
tbleEmployeeInfo has no data inside yet.
I would recommend using the INFORMATION_SCHEMA views. You can see all the columns and their types by doing:
select c.*
from INFORMATION_SCHEMA.COLUMNS c
where table_name = 'tbleEmployeeInfo';
(You might want to include the table_schema as well.)
To get the count, just use COUNT(*):
select count(*)
from INFORMATION_SCHEMA.COLUMNS c
where table_name = 'tbleEmployeeInfo';
SELECT COUNT(*)
FROM sys.columns
WHERE object_id = object_id('tblEmployeeInfo')

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%'