Select from a table only the columns that are not empty? - sql

I have a table with hundreds of columns:
------------------------------------------------
ID ColA ColB ColC Col D ... ColZZZ
------------------------------------------------
1 bla
2 foo
3 bar
4 baz
------------------------------------------------
I need to know which columns have no values in them (that is: which are empty '' not NULL)
I could create a query for every column:
select count(1) from [table] where [ColA] <> ''; -- returns 2, so not, not empty
select count(1) from [table] where [ColB] <> ''; -- returns 1, so no
select count(1) from [table] where [ColC] <> ''; -- returns 0, so yay! found and empty one
...
etc
But there has to be an easier way for this?
Is there a way to return [table] without the empty columns, in other words:
----------------------------
ID ColA ColB ColZZZ
----------------------------
1 bla
2 foo
3 bar
4 baz
----------------------------

Here is solution to it. I used this query before too search for empty columns across all tables. Slightly modified now to search for non-empty, it might have few extra parts not needed in you example.
You create a temp table to store column names that are not empty, and use cursor to create dynamic sql to search for them.
In the end, just generate another dynamic sql to select columns based on temp table results.
IF (OBJECT_ID('tempdb..#tmpRez') IS NOT NULL) DROP TABLE #tmpRez;
CREATE TABLE #tmpRez (TableName sysname, ColName sysname);
DECLARE crs CURSOR LOCAL FAST_FORWARD FOR
SELECT t.name, c.name FROM sys.tables t
INNER JOIN sys.columns c ON c.object_id=t.object_id
WHERE 1=1
AND t.name = 'Table1' -- OR your own condition
OPEN crs;
DECLARE #tbl sysname;
DECLARE #col sysname;
DECLARE #sql NVARCHAR(MAX);
FETCH NEXT FROM crs INTO #tbl,#col;
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #sql = 'IF EXISTS (SELECT * FROM ['+ #tbl+'] WHERE [' + #col + '] <> '''') INSERT INTO #tmpRez SELECT ''' + #tbl +''','''+ #col + '''';
EXEC(#sql);
FETCH NEXT FROM crs INTO #tbl,#col;
END;
CLOSE crs;
DEALLOCATE crs;
SELECT #sql = 'SELECT ' + STUFF((SELECT ',' + ColName FROM #tmpRez x
where x.TableName = y.TableName
FOR XML PATH ('')), 1, 1, '') + ' FROM ' + TableName
FROM #tmpRez y GROUP BY TableName
EXEC (#sql)

How about this to return the table with no empty columns:
SELECT * from table
WHERE column IS NOT NULL AND TRIM(column) <> ''
This to return the table with empty columns:
SELECT * from table
WHERE column IS NULL AND TRIM(column) = ''

Related

How to loop through a list of table names and see if a specific value in a column exists?

I have produced a table in SQL with a list of tables. This list of tables is stored under the column 'table_name'. I want to loop through each entry under 'table_name' and return a 1 if that table has a value in a specific column or 0 if that table does not have a value in a specific column.
How would I do that?
Edited With sample data
table_name
tabel1
table2
table3
table4
Pseudo Code
For i in table_name
if count(table_name["col_name"] = "value") > 0
return 1
else
return 0
Try this:
drop table if exists #t
create table #t (A int)
insert into #t
select 1
drop table if exists #t2
create table #t2 (A int)
insert into #t2
select 0
drop table if exists #tables
create table #tables (tab varchar(100))
declare
#loop table (rn int, tab varchar(100))
declare
#res table (cnt int)
declare
#i int=1
,#tab varchar (100)=''
,#query nvarchar (max)
insert into #tables
select '#t'
union all
select '#t2'
insert into #loop
select ROW_NUMBER () over (partition by (select 1) order by tab),tab from #tables
while #i<=(select max(rn) from #loop)
begin
select #tab=tab from #loop where rn=#i
set #query='select count(*) from '+#tab+' where a=1'
insert into #res
exec(#query)
if (select cnt from #res)>0 select 'Exists' else select 'Not Exists'
delete #res
set #i=#i+1
end
Assuming you have a singular column/value in question, you can try the following in SSMS:
DECLARE #Tables table ( table_name varchar(50) );
INSERT INTO #Tables VALUES
( 'Child' ), ( 'COS' ), ( 'CustomData' ), ( 'Misc' ), ( 'Misc2' );
DECLARE
#col varchar(50) = 'id', -- column to be queried
#val varchar(50) = '1', -- value to be queried
#sql varchar(MAX) = '' -- important! set to empty string;
SELECT
#sql = #sql + CASE WHEN LEN( #sql ) > 0 THEN ' UNION ' ELSE '' END
+ 'SELECT ' + QUOTENAME( table_name, '''' ) + ' AS [table_name], COUNT(*) AS [value_count] FROM [' + table_name + '] WHERE [' + #col + ']=' + QUOTENAME( #val, '''' )
FROM #Tables t WHERE EXISTS (
SELECT * FROM sys.columns c WHERE c.object_id = OBJECT_ID( t.table_name ) AND c.[name] = #col
);
EXEC( #sql );
In my environment this returns:
+------------+-------------+
| table_name | value_count |
+------------+-------------+
| Child | 1 |
| Misc | 1 |
| Misc2 | 0 |
+------------+-------------+
This is the (beautified) dynamic SQL created:
SELECT 'Child' AS [table_name], COUNT(*) AS [value_count] FROM [Child] WHERE [id]='1'
UNION
SELECT 'Misc' AS [table_name], COUNT(*) AS [value_count] FROM [Misc] WHERE [id]='1'
UNION
SELECT 'Misc2' AS [table_name], COUNT(*) AS [value_count] FROM [Misc2] WHERE [id]='1'
The EXISTS in the WHERE clause eliminates any tables that do not have the column in question, and thereby any errors related to it.

How to pass table name as parameter in select statement in SQL Sever

Table:
Col
------
Table1
table2
table3
Query:
select count(*)
from #tablename
I wanted to pass table1, table2, table3 as parameters for #tablename in the select query and get the count for each table
Desired output:
2 (table 1 count) 3 (table 2 count) 4 (table 3 count)
you can use dynamic sql and a cursor to run through them:
Create temp table for testing:
DECLARE #tablenametable TABLE(tablename VARCHAR(100));
INSERT INTO #tablenametable
VALUES('table1'), ('table2'), ('table3');
Use a cursor to run through all tablenames in the table
DECLARE #tablename VARCHAR(100);
DECLARE dbcursor CURSOR
FOR
SELECT tablename
FROM #tablenametable;
OPEN dbcursor;
FETCH NEXT FROM dbcursor INTO #tablename;
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #sql VARCHAR(MAX);
SET #sql = 'select count(*) from '+#tablename;
PRINT(#sql);
FETCH NEXT FROM dbcursor INTO #tablename;
END;
CLOSE dbcursor;
DEALLOCATE dbcursor;
Give the following results:
select count(*) from table1
select count(*) from table2
select count(*) from table3
Just change PRINT(#SQL) to EXEC(#SQL) when your happy with it
You can use dynamic sql query.
Query
declare #sql as varchar(max);
select #sql = stuff((
select ' union all '
+ 'select cast(count(*) as varchar(100))
+ ' + char(39) + '(' + [Col] +' Count)' + char(39)
+ ' as [table_counts] '
+ ' from ' + [col]
from [your_table_name]
for xml path('')
)
, 1, 11, ''
);
exec(#sql);
Find a demo here
As mentioned here, you have to use dynamic SQL.
First approach is where you specify table name yourself:
declare #tablename varchar(30), #SQL varchar(30)
set #tablename = 'Table1' --here you specify the name
set #SQL = concat('SELECT COUNT(*) FROM ', #tablename) --here you build the query
EXEC(#SQL)
Second approach lets you use table with names of tables:
declare #SQL varchar(8000)
set #SQL = ''
declare #TableNames table(name varchar(30))
insert into #TableNames values ('Table1'), ('Table2'), ('Table3')
--here you build the query
select #SQL = #SQL + ' SELECT ''' + name + ''' AS [TableName], COUNT(*) AS [Count] FROM ' + name + ' UNION ALL' from #TableNames
-- get rid of last "UNION ALL"
set #SQL = LEFT(#SQL, LEN(#SQL) - 10)
--execute the query
EXEC(#SQL)
The result of it will be:
TableName Count
Table1 3
Table2 6
Table3 4
You can use sys.dm_db_partition_stats like this [1]:
select
t.col tableName, sum(s.row_count) tableCount
from
yourTable t
join
sys.dm_db_partition_stats s
on
(object_name(s.object_id) = t.col )
and
(s.index_id < 2)
group by
t.col;
[1]. Related answer
One line output version will be:
select
sum(s.row_count), ' ('+t.col +' count) '
from
yourTable t
join
sys.dm_db_partition_stats s
on
(object_name(s.object_id) = t.col )
and
(s.index_id < 2)
group by
t.col
for xml path('');
output:
2 (Table1 count) 3 (table2 count) 4 (table3 count)

Is it possible to remove the cursor from this dynamic query?

Simplified example of what I have:
Two tables (table_1 and table_2) which have one similar column (Id) but also several "payload" columns with different names (col_1_1, col_2_1, col_2_2). Amount of "payload" columns is different for different tables.
I am interested in extracting the IDs from both tables into another table for rows which have all "payload" columns empty.
There is a list of all "payload" columns for all tables which can be used (#temp)
This is how it is done with cursor:
CREATE TABLE #temp (tab nvarchar(20) not null, col nvarchar(20) not null)
INSERT INTO #temp SELECT 'table_1','col_1_1' UNION SELECT 'table_2','col_2_1' UNION SELECT 'table_2','col_2_2'
DECLARE #table_name nvarchar(20)
DECLARE #sql nvarchar(max)
DECLARE curs CURSOR FOR (SELECT DISTINCT tab FROM #temp)
OPEN curs
FETCH NEXT FROM curs INTO #table_name
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #sql = ISNULL(#sql,'')+col+' IS NULL AND ' FROM #temp WHERE tab = #table_name
SET #sql += 'Id IS NOT NULL'
SET #sql = 'INSERT INTO #temp_master SELECT ID FROM '+#table_name+' WHERE '+#sql
print #sql
SET #sql = ''
FETCH NEXT FROM curs INTO #table_name
END
CLOSE curs
DEALLOCATE curs
This is the result:
INSERT INTO #temp_master SELECT ID FROM table_1 WHERE col_1_1 IS NULL AND Id IS NOT NULL
INSERT INTO #temp_master SELECT ID FROM table_2 WHERE col_2_1 IS NULL AND col_2_2 IS NULL AND Id IS NOT NULL
Is it possible to remove the cursor to get the same resulting dynamic query? The problem is that I am unable to have dynamic "IS NULL AND" part for different tables when I remove the cursor.
It's possible to get rid of that cursor. This is probably what you need:
CREATE TABLE #temp (tab nvarchar(20) not null, col nvarchar(20) not null)
INSERT INTO #temp SELECT 'table_1','col_1_1' UNION SELECT 'table_2','col_2_1' UNION SELECT 'table_2','col_2_2'
DECLARE #table_name nvarchar(20)
DECLARE #sql nvarchar(max) = ''
select #sql = 'INSERT INTO #temp_master SELECT ID FROM ' + t.tab + ' WHERE Id IS NOT NULL AND ' + substring(t.cols, 0, len(t.cols)-3) + '
' + #sql from
(
SELECT
distinct
t2.tab,
stuff(
(
select t1.col + cast(' IS NULL AND ' as varchar(max))
from #temp t1
WHERE t1.tab = t2.tab
order by t1.tab
for xml path('')
), 1, 0, '') AS cols
FROM
#temp t2
) as t
order by t.tab desc
print #sql
drop table #temp
That is a regular CONCAT question, you can find many approaches to accomplish it without cursor. One of approaches is a cursor by the way and it's not that bad for such a task.
Another and more popular - FOR XML which can guarantee row order if any defined:
DECLARE #sql VARCHAR(MAX)
CREATE TABLE #temp (tab nvarchar(20) not null, col nvarchar(20) not null)
INSERT INTO #temp SELECT 'table_1','col_1_1' UNION SELECT 'table_2','col_2_1' UNION SELECT 'table_2','col_2_2'
SET #sql = (SELECT (
SELECT '
INSERT INTO #temp_master (ID) SELECT t.ID FROM '+t.tab +' t WHERE t.Id IS NOT NULL'
+ (select ' AND t.' + tt.col + ' is NULL' from #temp tt WHERE tt.tab = t.tab FOR XML PATH(''), TYPE).value('.', 'varchar(max)')
FROM #temp t
GROUP BY t.tab
FOR XML PATH(''), TYPE).value('.', 'varchar(max)'))
PRINT #sql
DROP TABLE #temp
A little "tricky" thing is that you have two things to collaps:
many queries (separate for specific table)
many columns per table
So you there is one inner FOR XML to collapse columns per table and another - to combine all queries into one big script.

Find columns that contain only zeros

I'm working with SQL Server 2008. I have a list of column names on a table and I'd like to know how to use SQL to return the names of those columns which contain nothing but zero or NULL values.
declare #T table
(
Col1 int,
Col2 int,
Col3 int,
Col4 int
)
insert into #T values
(1, 0 , null, null),
(0, null, 0 , 1)
select U.ColName
from
(
select count(nullif(Col1, 0)) as Col1,
count(nullif(Col2, 0)) as Col2,
count(nullif(Col3, 0)) as Col3,
count(nullif(Col4, 0)) as Col4
from #T
) as T
unpivot
(C for ColName in (Col1, Col2, Col3, Col4)) as U
where U.C = 0
Result:
ColName
----------
Col2
Col3
The idea behind this is to count the non null values and only keep those with a count of 0.
COUNT will only count non null values.
NULLIF(ColX, 0) will make all 0 into null.
The inner query returns one row with four columns. UNPIVOT will turn it around so you have two columns and four rows.
Finally where U.C = 0 makes sure that you only get the columns that has no values other than null or 0.
Here is a brute force way, since you know all the column names.
CREATE TABLE dbo.splunge
(
a INT,
b INT,
c INT,
d INT
);
INSERT dbo.splunge VALUES (0,0,1,-1), (0,NULL,0,0), (0,0,0,NULL);
SELECT
cols = STUFF(
CASE WHEN MIN(COALESCE(a,0)) = MAX(COALESCE(a,0)) THEN ',a' ELSE '' END
+ CASE WHEN MIN(COALESCE(b,0)) = MAX(COALESCE(b,0)) THEN ',b' ELSE '' END
+ CASE WHEN MIN(COALESCE(c,0)) = MAX(COALESCE(c,0)) THEN ',c' ELSE '' END
+ CASE WHEN MIN(COALESCE(d,0)) = MAX(COALESCE(d,0)) THEN ',d' ELSE '' END,
1, 1, '')
FROM dbo.splunge;
-- result:
-- a,b
GO
DROP TABLE dbo.splunge;
You could probably generate much of this script instead of doing it manually, assuming you know the naming scheme or data type of the columns you want (or just by leaving off the where clause entirely and removing the columns you don't want manually).
SELECT CHAR(13) + CHAR(10) + ' + CASE WHEN MIN(COALESCE(' + name + ',0)) = '
+ 'MAX(COALESCE(' + name + ',0)) THEN '',' + name + ''' ELSE '''' END'
FROM sys.columns
WHERE [object_id] = OBJECT_ID('dbo.splunge')
-- AND system_type_id = 56
-- AND name LIKE '%some pattern%'
;
The output will look like the middle of the first query, so you can copy & paste and then remove the first + and add the surrounding STUFF and query...
Here's a way that works for any table:
declare #tableName nvarchar(max) = N'myTable'
declare #columnName nvarchar(max)
create table #zeros (column_name varchar(max))
declare c cursor local forward_only read_only for
select column_name
from information_schema.COLUMNS WHERE table_name = #tableName
open c
fetch next from c into #columnName
while ##FETCH_STATUS = 0
begin
declare #retval int
declare #sql nvarchar(max) =
N'set #retval = (select count(*) from ' + #tableName + N' where coalesce(' + #columnName + N', 0) <> 0)'
exec sp_executesql #sql, N'#retval int out', #retval=#retval out
select #retval
if #retval = 0
begin
insert into #zeros (column_name) values (#columnName)
end
fetch next from c into #columnName
end
close c
deallocate c
select * from #zeros
drop table #zeros

SQL to return first two columns of a table

Is there any SQL lingo to return JUST the first two columns of a table WITHOUT knowing the field names?
Something like
SELECT Column(1), Column(2) FROM Table_Name
Or do I have to go the long way around and find out the column names first? How would I do that?
You have to get the column names first. Most platforms support this:
select column_name,ordinal_position
from information_schema.columns
where table_schema = ...
and table_name = ...
and ordinal_position <= 2
There it´s
declare #select varchar(max)
set #select = 'select '
select #select=#select+COLUMN_NAME+','
from information_schema.columns
where table_name = 'TABLE' and ordinal_position <= 2
set #select=LEFT(#select,LEN(#select)-1)+' from TABLE'
exec(#select)
A dynamic query using for xml path will also do the job:
declare #sql varchar(max)
set #sql = (SELECT top 2 COLUMN_NAME + ',' from information_schema.columns where table_name = 'YOUR_TABLE_NAME_HERE' order by ordinal_position for xml path(''))
set #sql = (SELECT replace(#sql +' ',', ',''))
exec('SELECT ' + #sql + ' from YOUR_TABLE_NAME_HERE')
I wrote a stored procedure a while back to do this exact job. Even though in relational theory there is no technical column order SSMS is not completely relational. The system stores the order in which the columns were inserted and assigns an ID to them. This order is followed using the typical SELECT * statement which is why your SELECT statements appear to return the same order each time. In practice its never a good idea to SELECT * with anything as it doesn't lock the result order in terms of columns or rows. That said I think people get so stuck on 'you shouldn't do this' that they don't write scripts that actually can do it. Fact is there is predictable system behavior so why not use it if the task isn't super important.
This SPROC of course has caveats and is written in T-SQL but if your looking to just return all of the values with the same behavior of SELECT * then this should do the job pretty easy for you. Put in your table name, the amount of columns, and hit F5. It returns them in order from left to right the same as you'd be expecting. I limited it to only 5 columns but you can edit the logic if you need any more. Takes both temp and permanent tables.
EXEC OnlySomeColumns 'MyTable', 3
/*------------------------------------------------------------------------------------------------------------------
Document Title: The Unknown SELECT SPROC.sql
Created By: CR
Date: 4.28.2013
Purpose: Returns all results from temp or permanent table when not knowing the column names
SPROC Input Example: EXEC OnlySomeColumns 'MyTable', 3
--------------------------------------------------------------------------------------------------------------------*/
IF OBJECT_ID ('OnlySomeColumns', 'P') IS NOT NULL
DROP PROCEDURE OnlySomeColumns;
GO
CREATE PROCEDURE OnlySomeColumns
#TableName VARCHAR (1000),
#TotalColumns INT
AS
DECLARE #Column1 VARCHAR (1000),
#Column2 VARCHAR (1000),
#Column3 VARCHAR (1000),
#Column4 VARCHAR (1000),
#Column5 VARCHAR (1000),
#SQL VARCHAR (1000),
#TempTable VARCHAR (1000),
#PermanentTable VARCHAR (1000),
#ColumnNamesAll VARCHAR (1000)
--First determine if this is a temp table or permanent table
IF #TableName LIKE '%#%' BEGIN SET #TempTable = #TableName END --If a temporary table
IF #TableName NOT LIKE '%#%' BEGIN SET #PermanentTable = #TableName END --If a permanent column name
SET NOCOUNT ON
--Start with a few simple error checks
IF ( #TempTable = 'NULL' AND #PermanentTable = 'NULL' )
BEGIN
RAISERROR ( 'ERROR: Please select a TempTable or Permanent Table.',16,1 )
END
IF ( #TempTable <> 'NULL' AND #PermanentTable <> 'NULL' )
BEGIN
RAISERROR ( 'ERROR: Only one table can be selected at a time. Please adjust your table selection.',16,1 )
END
IF ( #TotalColumns IS NULL )
BEGIN
RAISERROR ( 'ERROR: Please select a value for #TotalColumns.',16,1 )
END
--Temp table to gather the names of the columns
IF Object_id('tempdb..#TempName') IS NOT NULL DROP TABLE #TempName
CREATE TABLE #TempName ( ID INT, Name VARCHAR (1000) )
--Select the column order from a temp table
IF #TempTable <> 'NULL'
BEGIN
--Verify the temp table exists
IF NOT EXISTS ( SELECT 1
FROM tempdb.sys.columns
WHERE object_id = object_id ('tempdb..' + #TempTable +'') )
BEGIN
RAISERROR ( 'ERROR: Your TempTable does not exist - Please select a valid TempTable.',16,1 )
RETURN
END
SET #SQL = 'INSERT INTO #TempName
SELECT column_id AS ID, Name
FROM tempdb.sys.columns
WHERE object_id = object_id (''tempdb..' + #TempTable +''')
ORDER BY column_id'
EXEC (#SQL)
END
--From a permanent table
IF #PermanentTable <> 'NULL'
BEGIN
--Verify the temp table exists
IF NOT EXISTS ( SELECT 1
FROM syscolumns
WHERE id = ( SELECT id
FROM sysobjects
WHERE Name = '' + #PermanentTable + '' ) )
BEGIN
RAISERROR ( 'ERROR: Your Table does not exist - Please select a valid Table.',16,1 )
RETURN
END
SET #SQL = 'INSERT INTO #TempName
SELECT colorder AS ID, Name
FROM syscolumns
WHERE id = ( SELECT id
FROM sysobjects
WHERE Name = ''' + #PermanentTable + ''' )
ORDER BY colorder'
EXEC (#SQL)
END
--Set the names of the columns
IF #TotalColumns >= 1 BEGIN SET #Column1 = (SELECT Name FROM #TempName WHERE ID = 1) END
IF #TotalColumns >= 2 BEGIN SET #Column2 = (SELECT Name FROM #TempName WHERE ID = 2) END
IF #TotalColumns >= 3 BEGIN SET #Column3 = (SELECT Name FROM #TempName WHERE ID = 3) END
IF #TotalColumns >= 4 BEGIN SET #Column4 = (SELECT Name FROM #TempName WHERE ID = 4) END
IF #TotalColumns >= 5 BEGIN SET #Column5 = (SELECT Name FROM #TempName WHERE ID = 5) END
--Create a select list of only the column names you want
IF Object_id('tempdb..#FinalNames') IS NOT NULL DROP TABLE #FinalNames
CREATE TABLE #FinalNames ( ID INT, Name VARCHAR (1000) )
INSERT #FinalNames
SELECT '1' AS ID, #Column1 AS Name UNION ALL
SELECT '2' AS ID, #Column2 AS Name UNION ALL
SELECT '3' AS ID, #Column3 AS Name UNION ALL
SELECT '4' AS ID, #Column4 AS Name UNION ALL
SELECT '5' AS ID, #Column5 AS Name
--Comma Delimite the names to insert into a select statement. Bracket the names in case there are spaces
SELECT #ColumnNamesAll = COALESCE(#ColumnNamesAll + '], [' ,'[') + Name
FROM #FinalNames
WHERE Name IS NOT NULL
ORDER BY ID
--Add an extra bracket at the end to complete the string
SELECT #ColumnNamesAll = #ColumnNamesAll + ']'
--Tell the user if they selected to many columns
IF ( #TotalColumns > 5 AND EXISTS (SELECT 1 FROM #FinalNames WHERE Name IS NOT NULL) )
BEGIN
SELECT 'This script has been designed for up to 5 columns' AS ERROR
UNION ALL
SELECT 'Only the first 5 columns have been selected' AS ERROR
END
IF Object_id('tempdb..#FinalNames') IS NOT NULL DROP TABLE ##OutputTable
--Select results using only the Columns you wanted
IF #TempTable <> 'NULL'
BEGIN
SET #SQL = 'SELECT ' + #ColumnNamesAll + '
INTO ##OutputTable
FROM ' + #TempTable + '
ORDER BY 1'
EXEC (#SQL)
END
IF #PermanentTable <> 'NULL'
BEGIN
SET #SQL = 'SELECT ' + #ColumnNamesAll + '
INTO ##OutputTable
FROM ' + #PermanentTable + '
ORDER BY 1'
EXEC (#SQL)
END
SELECT *
FROM ##OutputTable
SET NOCOUNT OFF
SQL doesn't understand the order of columns. You need to know the column names to get them.
You can look into querying the information_schema to get the column names. For example:
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
ORDER BY ordinal_position
LIMIT 2;
You can query the sysobject of the table to find out the first two column then dynamically generate the SQL statement you need.
If you want a permant object that you can query over and over again make a view for each table that only returns the first 2 columns. You can name the columns Column1 and Column2 or use the existing names.
If you want to return the first two columns from any table without any preprocessing steps create a stored procedure that queries the system information and executes a dynamic query that return the first two columns from the table.
Or do I have to go the long way around and find out the column names first? How would I do that?
It's pretty easy to do manually.
Just run this first
select * from tbl where 1=0
This statement works on all major DBMS without needing any system catalogs.
That gives you all the column names, then all you need to do is type the first two
select colname1, colnum2 from tbl