How to select dynamic header as value (SQL Server) - sql

I'm coding in SQL Server and encountered a problem.
I have Excel sheets that I have uploaded to SSMS. There is a value that is received as a name of a column (part of the header). In all sheets it's in the exact same location, but the value itself is dynamic and I can't expect it. I want to select those values.
For example:
Sheet 1
Name
ID
* 675438 *
Phone
.... ........
.. ...
................
.......
.... ........
.. ...
................
.......
Sheet 2
Name
ID
* 321459 *
Phone
.... ........
.. ...
................
.......
.... ........
.. ...
................
.......
And that's the format so on
I want to select the starred values that are received as headers.
Any help would be appreciated! Thanks in advance.

Depending on how you need to select this, you can determine the name of the column from meta-data, and dynamically execute the SQL. This assumes the ordinal position of the column is always the same (3 in your case). Your situation may be different, so just know that you can fetch the column name dynamically if it helps.
declare #col1 as varchar(128)
declare #tableName as varchar(128)
declare #sql nvarchar(MAX)
SELECT #tableName = 'yourTableName'
select #col1 = column_name from information_schema.columns where table_name = #tableName
and ordinal_position = 3
SET #sql = 'SELECT ' + #col1 + ' FROM ' + #tableName
EXEC(#sql)

You can get the ordinal position of the column you are looking for using this query:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'YOUR_TABLE'
And then use it in a dynamic SQL statement to select the name of it using that position:
declare #COLUMN varchar(max)
select #COLUMN = column_name FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'YOUR_TABLE' and ORDINAL_POSITION = 'COLUMN_NUMBER'
DECLARE #sqlcmd VARCHAR(MAX)
SET #sqlcmd = 'SELECT ' + QUOTENAME(#COLUMN) + ' from YOUR_TABLE';
EXEC (#sqlcmd);

Related

SQL - How do I get 1 empty column per row in a related table?

I am trying to write a SQL query that adds a certain amount of empty columns, based on the number of rows in a related table (t1) for a Crystal Report. These columns should have the header of the name of the dataset.
So it should look something like this:
However I would need to change the script each time a new row gets added (e.g. opening a store - not very often, but it does happen).
I thought about using the pivot function, but I believe the number of rows must be defined - plus, there is no calculation / aggregation happening.
Does anybody have an idea on how to solve this?
As Larnu already mentioned, dynamic SQL would be one way to go. I would suggest using a combination of XML PATH and dynamic SQL. Following an example:
DECLARE #colList VARCHAR(MAX) = (SELECT STUFF((SELECT ',NULL as t1_row' + cast(col1 AS varchar(3))
FROM MyTable
FOR XML PATH('')) ,1,1,'') AS Txt
)
DECLARE #stmt VARCHAR(MAX) = 'SELECT Col1, Col2, Col3, ' + #colList + ' FROM MyTable'
EXEC (#stmt)
I was able to achieve the result using dynamic SQL.
The Script looks something like this:
DECLARE #STRSQL NVARCHAR(MAX) = 'WITH a AS (SELECT ';
DECLARE #Kst nvarchar(6);
DECLARE #Markt NVARCHAR(30);
DECLARE #SCHEMA_NAME VARCHAR(50) = 'XTRADE';
DECLARE C1 CURSOR FOR
SELECT NUMMER, BEZEICHNUNG
from XTRADE.KUNDE
where NUMMER > 99 and NUMMER not in (194, 196, 198)
and (DATUM_SCHLIESSUNG > GETDATE() or DATUM_SCHLIESSUNG is null)
order by BEZEICHNUNG
OPEN C1
PRINT #Kst + ' ' + #Markt
FETCH NEXT
FROM C1 into #Kst, #Markt
while ##FETCH_STATUS = 0
BEGIN
SET #STRSQL = #STRSQL + 'null as [' + #Markt + '], '
FETCH NEXT
FROM C1 into #Kst, #Markt
END
CLOSE C1
DEALLOCATE C1;
SET #STRSQL = left(#STRSQL, len(#Strsql) - 1) + ')'
DECLARE #Statement nvarchar(max) = ', b as (select 1 as Col1, 1 as Col2, 5 as Col3 union all select 2,2,12 union all select 3, 3, 42)';
DECLARE #Exec nvarchar(max) = #STRSQL + #Statement + 'select * from b cross join a';
print #Exec;
exec sp_executesql #Exec

How to return all values in the first column of a table without specifying column's name?

I need to create a dynamic sql query in order to return all values in the first column of a table. The table's name needs to be a variable #tableName ( i will run this query for multiple tables depending on several conditions). Also, i don't know exactly the first column's name but it is formed out of Id_#tableName .
I need something like below but written dinamically:
select
(select column_name from INFORMATION_SCHEMA.columns where table_Name= #tableName and ordinal_position=1)
from #tableName
Could you please help me? Thank you in advance!
USE AdventureWorks;
GO
DECLARE #ObjectName SYSNAME = 'Sales.SalesOrderHeader';
DECLARE #SQL NVARCHAR(MAX);
SELECT
#SQL = 'SELECT ' + QUOTENAME(name) + ' FROM ' + #ObjectName
FROM
sys.columns
WHERE
object_id = OBJECT_ID(#ObjectName)
AND column_id = 1;
EXEC sp_executesql #SQL;

Counting rows in the table which have 1 or more missing values

Could you please advise how to find the number of rows in the table which have 1 or more missing values? The missing values are represented in my table by question marks = '?'. The table has 15 columns and ~50k rows. When I run the following query for some of the columns I can receive some results:
SELECT
COUNT(*)
FROM table_name
WHERE column_name ='?'
However I have also columns which bring me result: "Error converting data type varchar to float"
I would like to be able to find the number of rows in the table which have 1 or more missing values using 1 query/not run separately for each column.
Thank you in advance for your support!
Select Count(*)
From mySchema.myTable
Where Cast(Col1 As NVarChar(128)) +
Cast(Col2 As NVarChar(128)) +
Cast(Coln As NVarChar(128)) Like '%?%'
It's ugly and WILL be slow and you may need to modify the Casts accordingly, but should do the trick.
This should work for any column:
select count(*)
from table_name
where column_name is null or cast(column_name as varchar(255)) = '?';
Try following query:
Just set table name and it will get all columns
Also you can give value_to_match like '?' in your case or any other if you want.
DECLARE #table_name nvarchar(max) = 'table_name'
DECLARE #value_to_match nvarchar(max) = '1'
DECLARE #query nvarchar(max) = ''
DECLARE #Condition nvarchar(max) = ' OR ' -- 1 OR when you want to count row if any column has that value -- 2 when you want all all columns to have same value
SELECT #query = #query + ' cast(' + COLUMN_NAME + ' as nvarchar(500)) = ''' + #value_to_match + '''' + #Condition FROM informatioN_schema.columns WHERE table_name = #table_name
if ##rowcount = 0
BEGIN
SELECT 'Table doesn''t Exists'
RETURN
END
SELECT #query = LEFT(#query,LEN(#query)-3)
PRINT ('select count(9) FROM ' + #table_name + ' WHERE ' + #query)
EXEC ('select count(9) FROM ' + #table_name + ' WHERE ' + #query)

Using dynamic SQL to specify a column name by adding a variable to simple sql query

sql 2005/ sql 2008
Declare #temp nvarchar(1000)
set #temp = 'ABC'
select col1,col2 from tableA
Along with select query, how to add a variable to the select query ?
expected output :-
select col1,col2,#temp as [col3] from tableA
Where #temp specifies the name of a column in tableA.
If you are trying to specify the column name dynamically, you could take a look at executing dynamic sql. However, you should make sure to read about the dangers of this approach first:
http://www.sommarskog.se/dynamic_sql.html
From that page, there is a sample that shows dynamically specifying the table name -- you could change it so it dynamically specifies the column name instead:
CREATE PROCEDURE general_select #tblname nvarchar(128),
#key varchar(10),
#debug bit = 0 AS
DECLARE #sql nvarchar(4000)
SET #sql = 'SELECT col1, col2, col3
FROM dbo.' + quotename(#tblname) + '
WHERE keycol = #key'
IF #debug = 1 PRINT #sql
EXEC sp_executesql #sql, N'#key varchar(10)', #key = #key
So for example if you had a table 'MyTable' with columns named 'x', 'y', and 'z', it might look like:
DECLARE #columnName nvarchar(128)
DECLARE #sql nvarchar(4000)
set #columnName = 'z'
SET #sql = 'SELECT x, y, ' + #columnName + ' from MyTable'
EXEC sp_executesql #sql, N'#columnName varchar(128)', #columnName = #columnName
Something like this:
select col1,col2 from tableA WHERE col1 = #temp
Or this:
select col1,col2,#temp as col3 from tableA WHERE col1 = #temp
Or this:
select col1,col2,#temp as col3 from tableA
Or if #temp is a column name, then maybe you're looking for a dynamic query?
SET #temp = 'select col1,col2, ' + #temp + ' as col3 from tableA'
EXEC sp_executesql #temp
...

similar to SELECT * in sql but with only a row

When we do SELECT * FROM table we get all records in a table, If I want to get only a row but do not know the number of columns
like
id att1 att2 att3.... attx
-------------------------------
1 45 5 3 7
How do I do a select statement that returns all columns?
I know I must use
from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'myTable'
and a Where clause: WHERE id = 1
but again I do not know the number of columns...
Just add a where clause to the end of the #sql statement to limit your selection to the rows you want:
declare #cols nvarchar(max)
select #cols = coalesce(#cols + ', ' + column_name, column_name)
from information_schema.COLUMNS
where TABLE_NAME = 'mytable'
declare #sql nvarchar(max)
select #sql = 'select ' + #cols + ' from myTable where Id = 1'
exec sp_executesql #sql
The * means that you want all columns, not all "records".
select *
from YourTable
where ID = 1
There is no need to know the number of columns if you are interesting in pulling out the details of all. Just give the where condition with select *.