similar to SELECT * in sql but with only a row - sql

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 *.

Related

Get data from tables that I have from another query

I'm trying to get data from all tables that I have from another query as follows:
DECLARE #count int
SET #count = (SELECT COUNT(*) FROM (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%Project%') AS SUBQUERY)
WHILE(#count!=0)
BEGIN
SELECT * from (SELECT TABLE_NAME from (SELECT TABLE_NAME,
ROW_NUMBER() over (order by table_name) as row_number
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%Project%') as sub
WHERE row_number = #count) as another_sub;
SET #count = #count-1
end
What I get with this right now is 5 table names LIKE '%Project%'. I want to get the data from all of these 5 tables, not just their names. Also I don't want to join or union the tables. How can I achieve this?
DECLARE #SQL varchar(max) = '';
SELECT #SQL = #SQL + 'SELECT * FROM ' + QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%Project%';
print #SQL;
--EXEC(#SQL);

Display Count and distinct values for all columns in a table

I have a table with 700 columns. I am trying to get a list of distinct values for each column and their count. I am using the below query to get the result for 1 column
Select distinct col1, count(*) from MyTable group by 1.
Result:
col1 count(*)
a 10
b 20
c 40
How can I get the result for all columns using a single query in the most optimal way?
The basic query is:
select col001, count(*) from MyTable group by col001 union all
select col002, count(*) from MyTable group by col002 union all
. . .
select col700, count(*) from MyTable group by col700 ;
Not pleasant, but that is basically the query you need to run. SQL doesn't really do multiple independent aggregations more efficiently than doing them separately (even using grouping sets, in my experience).
You can construct the query. One way is to run something like this:
select replace(replace('select [col], count(*) as cnt from [tab] group by [col] union all ',
'[tab]', table_name
), '[col]', column_name
)
from information_schema.columns
where table_name = 'mytable' and table_schema = ??;
You can then copy the generated SQL (removing the final union all) and run it.
Note: That above is generic; the exact code might differ by database.
A list with distinct values for each column is impossible. What if column A has 5 distinct values and column B has 7. What would your list look like?
The other question is easier, but as #Gordon Linoff states, takes 2 steps. Elaborating on his answer, for MS SQL:
select replace(replace(' count(distinct([col])) as [col],',
'[tab]', table_name
), '[col]', column_name
)
from information_schema.columns
where table_name = 'your_table';
Copy the results and paste them in a new query window between.
SELECT
[[results query 1]]
FROM your_table
Remember to delete the last ',' from query 1 results.
Replace [table name] with the table you need counts for.
DECLARE #table varchar(100) = '[table name]'
DECLARE #i INT = 1, #cntOUT int, #SQL nvarchar(500) = ''
DECLARE #ParmDef nvarchar(500) = N'#cnt int OUTPUT';
SELECT column_id, name, 0 as record_count
INTO #T1
FROM sys.all_columns c
WHERE c.object_id = (SELECT object_id FROM sys.objects WHERE name = #table AND type = 'U')
WHILE #i <= (SELECT MAX(column_id) FROM #T1)
BEGIN
SELECT #SQL = 'SELECT #cnt = COUNT(DISTINCT ' + name + ') FROM ' + #table + ';'
FROM #T1 WHERE column_id = #i;
EXECUTE sp_executesql #stmt = #SQL, #ParmDefinition = #ParmDef, #cnt = #cntOUT OUTPUT;
UPDATE #T1 SET record_count = #cntOUT WHERE column_id = #i
SET #i = #i + 1
END
SELECT * FROM #T1
--DROP TABLE #T1

Check if set of rows fall in specific values in SQL?

I want to check if a given table has specific column names, I want it to return true if it has them all and if one column name doesn't exist I want it to return false, this is my query :
SELECT COLUMN_NAME
FROM db.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable'
I want to check if these names in the query result:
('UpdatedDate', 'CreatedDate', 'UpdatedBy')
If you know count of list this query help you
SELECT COUNT(COLUMN_NAME)
FROM db.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MyTable' AND COLUMN_NAME IN ('UpdatedDate', 'CreatedDate', 'UpdatedBy')
GROUP BY COLUMN_NAME HAVING COUNT(COLUMN_NAME) = 3;
Create a table variable with the column names which we need to check with information_schema.columns. Then do a check between the table variable and information_schema.columns. Not sure how efficient is this.
Query
declare #cols as varchar(max) = 'UpdatedDate,CreatedDate,UpdatedBy';
declare #cols2 as varchar(max) = '(' + char(39);
set #cols2 += replace(#cols, ',', '''),(''') + ''');';
declare #sql as varchar(max) = 'declare #tbl as table([col] varchar(1000));';
set #sql += 'insert into #tbl values' + #cols2;
set #sql += 'declare #tot as int;set #tot = (select count(*) from #tbl);';
set #sql += 'select case when count(*) = #tot
then ''true'' else ''false'' end as [status]
from #tbl t1 where exists(
select 1 from information_schema.columns t2
where t1.[col] = t2.[column_name]
and t2.[table_name] = ''MyTable'');';
exec(#sql);

Select columns whose name is not present in another table

Is there a way to only select the columns whose names are not present on another table? For example
Table A Column B
ID | Name | Address Address
-----------------------
1 | Daniel | dummy
In this example my select statement should be like this:
select ID, Name from Column A
I've seen people talking about dynamic SQL but I can't find a decent example to solve my issue, any help is much appreciated.
Here is a version of the way you would do this using dynamic SQL:
declare #cols varchar(max);
set #cols = NULL;
select #cols = coalesce(#cols + ', ' + column_name, column_name)
from information_schema.columns ca
where ca.table_name = 'A' and
ca.column_name not in (select cb.column_name
from information_schema.columns cb
where cb.table_name = 'B'
);
declare #sql varchar(max);
set #sql = 'select [cols] from A';
set #sql = replace(#sql, '[cols]', #cols);
exec sp_executesql #sql;
This is a bit simplified to show how the information_schema tables can be sued. It will work in many circumstances, but is not maximally general:
It doesn't take schema name into account.
It assumes all names are simple ASCII.
It does not escape the column names (assuming the names do not need to be escaped).
Select the other table in the WHERE clause.
SELECT ID, NAME
FROM ColumnA
WHERE NAME NOT IN (SELECT NAME FROM COLUMNB)

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)