How select all columns count of all tables by date - sql

Today I have this query that returns all rows from all tables. But now I want to add a new column that would be the number of records in the last year. Most tables have a column called "DateInsert".
I have this:
SELECT
SCHEMA_NAME(t.[schema_id]) AS [SCHEMA],
OBJECT_NAME(p.[object_id]) AS [NOME_TABELA],
SUM(p.[rows]) AS [ROW_COUNT]
FROM [sys].[partitions] p
INNER JOIN [sys].[tables](NOLOCK) t ON p.[object_id] = t.[object_id]
WHERE p.[index_id] < 2
GROUP BY p.[object_id]
,t.[schema_id]
ORDER BY [ROW_COUNT] desc
How do i add a new column counting rows from the last year only?

Assuming, each table has DateInsert column. You can try using Dynamic SQL to prepare the count for each table from last year in one temporary table and then you can Join that temp table with your final query.
Something like this
Please note that, if any of your table dont have DateInsert Column, this query will fail. In order to look at list of tables, you can prepare the dynamic SQL for those tables only
DECLARE #SQLQuery NVARCHAR(MAX)
-- Preparing Dynamic SQL
SELECT #SQLQuery = STUFF(
(SELECT CONCAT('UNION SELECT ''', name ,''' AS [TableName], COUNT(1) AS [NoOfRowsFromLastYear] FROM ['
, name
, '] WITH (NOLOCK) WHERE YEAR(DateInsert) = (YEAR(GETDATE())-1)')
FROM [sys].[tables]
--WHERE name in ('TableName')
FOR XML PATH(''))
, 1, LEN('UNION '), ''
)
SELECT #SQLQuery = CONCAT('SELECT * INTO ##TableDetail FROM (', #SQLQuery, ') DataSet')
-- Check for table, if available, drop it
IF OBJECT_ID('tempdb..##TableDetail') IS NOT NULL DROP TABLE ##TableDetail;
-- Execute prepared query
EXECUTE sp_executesql #SQLQuery
-- Final Query with [ROW_COUNT_FROM_LAST_YEAR]
SELECT
SCHEMA_NAME(t.[schema_id]) AS [SCHEMA],
OBJECT_NAME(p.[object_id]) AS [NOME_TABELA],
SUM(p.[rows]) AS [ROW_COUNT],
td.NoOfRowsFromLastYear AS [ROW_COUNT_FROM_LAST_YEAR]
FROM [sys].[partitions] p
INNER JOIN [sys].[tables](NOLOCK) t ON p.[object_id] = t.[object_id]
INNER JOIN ##TableDetail td ON td.[TableName] = t.name
WHERE p.[index_id] < 2
GROUP BY p.[object_id]
,t.[schema_id]
,td.NoOfRowsFromLastYear
ORDER BY [ROW_COUNT] desc

Related

Create a view in SQL with a row_count column [duplicate]

How to list row count of each table in the database. Some equivalent of
select count(*) from table1
select count(*) from table2
...
select count(*) from tableN
I will post a solution but other approaches are welcome
If you're using SQL Server 2005 and up, you can also use this:
SELECT
t.NAME AS TableName,
i.name as indexName,
p.[Rows],
sum(a.total_pages) as TotalPages,
sum(a.used_pages) as UsedPages,
sum(a.data_pages) as DataPages,
(sum(a.total_pages) * 8) / 1024 as TotalSpaceMB,
(sum(a.used_pages) * 8) / 1024 as UsedSpaceMB,
(sum(a.data_pages) * 8) / 1024 as DataSpaceMB
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a ON p.partition_id = a.container_id
WHERE
t.NAME NOT LIKE 'dt%' AND
i.OBJECT_ID > 255 AND
i.index_id <= 1
GROUP BY
t.NAME, i.object_id, i.index_id, i.name, p.[Rows]
ORDER BY
object_name(i.object_id)
In my opinion, it's easier to handle than the sp_msforeachtable output.
A snippet I found at http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=21021 that helped me:
select t.name TableName, i.rows Records
from sysobjects t, sysindexes i
where t.xtype = 'U' and i.id = t.id and i.indid in (0,1)
order by TableName;
To get that information in SQL Management Studio, right click on the database, then select Reports --> Standard Reports --> Disk Usage by Table.
SELECT
T.NAME AS 'TABLE NAME',
P.[ROWS] AS 'NO OF ROWS'
FROM SYS.TABLES T
INNER JOIN SYS.PARTITIONS P ON T.OBJECT_ID=P.OBJECT_ID;
As seen here, this will return correct counts, where methods using the meta data tables will only return estimates.
CREATE PROCEDURE ListTableRowCounts
AS
BEGIN
SET NOCOUNT ON
CREATE TABLE #TableCounts
(
TableName VARCHAR(500),
CountOf INT
)
INSERT #TableCounts
EXEC sp_msForEachTable
'SELECT PARSENAME(''?'', 1),
COUNT(*) FROM ? WITH (NOLOCK)'
SELECT TableName , CountOf
FROM #TableCounts
ORDER BY TableName
DROP TABLE #TableCounts
END
GO
sp_MSForEachTable 'DECLARE #t AS VARCHAR(MAX);
SELECT #t = CAST(COUNT(1) as VARCHAR(MAX))
+ CHAR(9) + CHAR(9) + ''?'' FROM ? ; PRINT #t'
Output:
Well luckily SQL Server management studio gives you a hint on how to do this.
Do this,
start a SQL Server trace and open the activity you are doing (filter
by your login ID if you're not alone and set the application Name
to Microsoft SQL Server Management Studio), pause the trace and discard any results you have recorded till now;
Then, right click a table and select property from the pop up menu;
start the trace again;
Now in SQL Server Management studio select the storage property item on the left;
Pause the trace and have a look at what TSQL is generated by microsoft.
In the probably last query you will see a statement starting with exec sp_executesql N'SELECT
when you copy the executed code to visual studio you will notice that this code generates all the data the engineers at microsoft used to populate the property window.
when you make moderate modifications to that query you will get to something like this:
SELECT
SCHEMA_NAME(tbl.schema_id)+'.'+tbl.name as [table], --> something I added
p.partition_number AS [PartitionNumber],
prv.value AS [RightBoundaryValue],
fg.name AS [FileGroupName],
CAST(pf.boundary_value_on_right AS int) AS [RangeType],
CAST(p.rows AS float) AS [RowCount],
p.data_compression AS [DataCompression]
FROM sys.tables AS tbl
INNER JOIN sys.indexes AS idx ON idx.object_id = tbl.object_id and idx.index_id < 2
INNER JOIN sys.partitions AS p ON p.object_id=CAST(tbl.object_id AS int) AND p.index_id=idx.index_id
LEFT OUTER JOIN sys.destination_data_spaces AS dds ON dds.partition_scheme_id = idx.data_space_id and dds.destination_id = p.partition_number
LEFT OUTER JOIN sys.partition_schemes AS ps ON ps.data_space_id = idx.data_space_id
LEFT OUTER JOIN sys.partition_range_values AS prv ON prv.boundary_id = p.partition_number and prv.function_id = ps.function_id
LEFT OUTER JOIN sys.filegroups AS fg ON fg.data_space_id = dds.data_space_id or fg.data_space_id = idx.data_space_id
LEFT OUTER JOIN sys.partition_functions AS pf ON pf.function_id = prv.function_id
Now the query is not perfect and you could update it to meet other questions you might have, the point is, you can use the knowledge of microsoft to get to most of the questions you have by executing the data you're interested in and trace the TSQL generated using profiler.
I kind of like to think that MS engineers know how SQL server work and, it will generate TSQL that works on all items you can work with using the version on SSMS you are using so it's quite good on a large variety releases prerviouse, current and future.
And remember, don't just copy, try to understand it as well else you might end up with the wrong solution.
Walter
This approaches uses string concatenation to produce a statement with all tables and their counts dynamically, like the example(s) given in the original question:
SELECT COUNT(*) AS Count,'[dbo].[tbl1]' AS TableName FROM [dbo].[tbl1]
UNION ALL SELECT COUNT(*) AS Count,'[dbo].[tbl2]' AS TableName FROM [dbo].[tbl2]
UNION ALL SELECT...
Finally this is executed with EXEC:
DECLARE #cmd VARCHAR(MAX)=STUFF(
(
SELECT 'UNION ALL SELECT COUNT(*) AS Count,'''
+ QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME)
+ ''' AS TableName FROM ' + QUOTENAME(t.TABLE_SCHEMA) + '.' + QUOTENAME(t.TABLE_NAME)
FROM INFORMATION_SCHEMA.TABLES AS t
WHERE TABLE_TYPE='BASE TABLE'
FOR XML PATH('')
),1,10,'');
EXEC(#cmd);
The first thing that came to mind was to use sp_msForEachTable
exec sp_msforeachtable 'select count(*) from ?'
that does not list the table names though, so it can be extended to
exec sp_msforeachtable 'select parsename(''?'', 1), count(*) from ?'
The problem here is that if the database has more than 100 tables you will get the following error message:
The query has exceeded the maximum
number of result sets that can be
displayed in the results grid. Only
the first 100 result sets are
displayed in the grid.
So I ended up using table variable to store the results
declare #stats table (n sysname, c int)
insert into #stats
exec sp_msforeachtable 'select parsename(''?'', 1), count(*) from ?'
select
*
from #stats
order by c desc
Fastest way to find row count of all tables in SQL Refreence (http://www.codeproject.com/Tips/811017/Fastest-way-to-find-row-count-of-all-tables-in-SQL)
SELECT T.name AS [TABLE NAME], I.rows AS [ROWCOUNT]
FROM sys.tables AS T
INNER JOIN sys.sysindexes AS I ON T.object_id = I.id
AND I.indid < 2
ORDER BY I.rows DESC
I want to share what's working for me
SELECT
QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) AS [TableName]
, SUM(sdmvPTNS.row_count) AS [RowCount]
FROM
sys.objects AS sOBJ
INNER JOIN sys.dm_db_partition_stats AS sdmvPTNS
ON sOBJ.object_id = sdmvPTNS.object_id
WHERE
sOBJ.type = 'U'
AND sOBJ.is_ms_shipped = 0x0
AND sdmvPTNS.index_id < 2
GROUP BY
sOBJ.schema_id
, sOBJ.name
ORDER BY [TableName]
GO
The database is hosted in Azure and the final result is:
Credit: https://www.mssqltips.com/sqlservertip/2537/sql-server-row-count-for-all-tables-in-a-database/
Here is my take on this question. It contains all schemas and lists only tables with rows. YMMV
select distinct schema_name(t.schema_id) as schema_name, t.name as
table_name, p.[Rows]
from sys.tables as t
INNER JOIN sys.indexes as i ON t.OBJECT_ID = i.object_id
INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id =
p.index_id
where p.[Rows] > 0
order by schema_name;
If you use MySQL >4.x you can use this:
select TABLE_NAME, TABLE_ROWS from information_schema.TABLES where TABLE_SCHEMA="test";
Keep in mind that for some storage engines, TABLE_ROWS is an approximation.
The accepted answer didn't work for me on Azure SQL, here's one that did, it's super fast and did exactly what I wanted:
select t.name, s.row_count
from sys.tables t
join sys.dm_db_partition_stats s
ON t.object_id = s.object_id
and t.type_desc = 'USER_TABLE'
and t.name not like '%dss%'
and s.index_id = 1
order by s.row_count desc
You could try this:
SELECT OBJECT_SCHEMA_NAME(ps.object_Id) AS [schemaname],
OBJECT_NAME(ps.object_id) AS [tablename],
row_count AS [rows]
FROM sys.dm_db_partition_stats ps
WHERE OBJECT_SCHEMA_NAME(ps.object_Id) <> 'sys' AND ps.index_id < 2
ORDER BY
OBJECT_SCHEMA_NAME(ps.object_Id),
OBJECT_NAME(ps.object_id)
This sql script gives the schema, table name and row count of each table in a database selected:
SELECT SCHEMA_NAME(schema_id) AS [SchemaName],
[Tables].name AS [TableName],
SUM([Partitions].[rows]) AS [TotalRowCount]
FROM sys.tables AS [Tables]
JOIN sys.partitions AS [Partitions]
ON [Tables].[object_id] = [Partitions].[object_id]
AND [Partitions].index_id IN ( 0, 1 )
-- WHERE [Tables].name = N'name of the table'
GROUP BY SCHEMA_NAME(schema_id), [Tables].name
order by [TotalRowCount] desc
Ref: https://blog.sqlauthority.com/2017/05/24/sql-server-find-row-count-every-table-database-efficiently/
Another way of doing this:
SELECT o.NAME TABLENAME,
i.rowcnt
FROM sysindexes AS i
INNER JOIN sysobjects AS o ON i.id = o.id
WHERE i.indid < 2 AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0
ORDER BY i.rowcnt desc
I think that the shortest, fastest and simplest way would be:
SELECT
object_name(object_id) AS [Table],
SUM(row_count) AS [Count]
FROM
sys.dm_db_partition_stats
WHERE
--object_schema_name(object_id) = 'dbo' AND
index_id < 2
GROUP BY
object_id
USE DatabaseName
CREATE TABLE #counts
(
table_name varchar(255),
row_count int
)
EXEC sp_MSForEachTable #command1='INSERT #counts (table_name, row_count) SELECT ''?'', COUNT(*) FROM ?'
SELECT table_name, row_count FROM #counts ORDER BY table_name, row_count DESC
DROP TABLE #counts
From this question:
https://dba.stackexchange.com/questions/114958/list-all-tables-from-all-user-databases/230411#230411
I added record count to the answer provided by #Aaron Bertrand that lists all databases and all tables.
DECLARE #src NVARCHAR(MAX), #sql NVARCHAR(MAX);
SELECT #sql = N'', #src = N' UNION ALL
SELECT ''$d'' as ''database'',
s.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''schema'',
t.name COLLATE SQL_Latin1_General_CP1_CI_AI as ''table'' ,
ind.rows as record_count
FROM [$d].sys.schemas AS s
INNER JOIN [$d].sys.tables AS t ON s.[schema_id] = t.[schema_id]
INNER JOIN [$d].sys.sysindexes AS ind ON t.[object_id] = ind.[id]
where ind.indid < 2';
SELECT #sql = #sql + REPLACE(#src, '$d', name)
FROM sys.databases
WHERE database_id > 4
AND [state] = 0
AND HAS_DBACCESS(name) = 1;
SET #sql = STUFF(#sql, 1, 10, CHAR(13) + CHAR(10));
PRINT #sql;
--EXEC sys.sp_executesql #sql;
You can copy, past and execute this piece of code to get all table record counts into a table. Note: Code is commented with instructions
create procedure RowCountsPro
as
begin
--drop the table if exist on each exicution
IF OBJECT_ID (N'dbo.RowCounts', N'U') IS NOT NULL
DROP TABLE dbo.RowCounts;
-- creating new table
CREATE TABLE RowCounts
( [TableName] VARCHAR(150)
, [RowCount] INT
, [Reserved] NVARCHAR(50)
, [Data] NVARCHAR(50)
, [Index_Size] NVARCHAR(50)
, [UnUsed] NVARCHAR(50))
--inserting all records
INSERT INTO RowCounts([TableName], [RowCount],[Reserved],[Data],[Index_Size],[UnUsed])
-- "sp_MSforeachtable" System Procedure, 'sp_spaceused "?"' param to get records and resources used
EXEC sp_MSforeachtable 'sp_spaceused "?"'
-- selecting data and returning a table of data
SELECT [TableName], [RowCount],[Reserved],[Data],[Index_Size],[UnUsed]
FROM RowCounts
ORDER BY [TableName]
end
I have tested this code and it works fine on SQL Server 2014.
SELECT ( Schema_name(A.schema_id) + '.' + A.NAME ) AS TableName,
Sum(B.rows)AS RecordCount
FROM sys.objects A INNER JOIN sys.partitions B
ON A.object_id = B.object_id WHERE A.type = 'U'
GROUP BY A.schema_id,A.NAME ;
QUERY_PHOTO
QUERY_RESULT_PHOTO
Shnugo's answer is the ONLY one that works in Azure with Externa Tables. (1) Azure SQL doesn't support sp_MSforeachtable at all and (2) rows in sys.partitions for an External table is always 0.
select T.object_id, T.name, I.indid, I.rows
from Sys.tables T
left join Sys.sysindexes I
on (I.id = T.object_id and (indid =1 or indid =0 ))
where T.type='U'
Here indid=1 means a CLUSTERED index and indid=0 is a HEAP

Comparing table names across multiple SQL Server databases

I am trying to run a SQL Server export which compares the table names listed in three or more databases on a SQL Server instance (actually the number is a lot higher!)
I can use something simple like the following to get a list of all of the tables in a particular database.
SELECT [name]
FROM DB1.sys.tables
What I would like to be able to do is to be able to join these for multiple databases to create a single view to spot differences (and similarities).
So for example if I have three databases with the following tables
DB1:
Customers
Orders
Products
DB2:
Products
Orders
DB3:
Products
Suppliers
How could I join them all together to get something like the following?
DB1
DB2
DB3
Customers
NULL
NULL
Orders
Orders
NULL
Products
Products
Products
NULL
NULL
Suppliers
Thanks!
This script should give you what you are looking for and can be easily extended by fiddling with the WHERE clause around line 20
--Set up some global temporary tables
CREATE TABLE ##all_tables(
[database_name] sysname,
[table_name] sysname
)
CREATE TABLE ##tables_for_relevant_dbs(
[database_name] sysname,
[table_name] sysname
)
--Capture a list of all the tables in all of the databases on the instance
exec sp_MSforeachdb 'insert into ##all_tables select ''?'', [name] from [?].sys.tables'
--Filter to get the tables from the relevant databases
INSERT INTO ##tables_for_relevant_dbs
SELECT dbs.[database_name],tbls.[table_name]
FROM (select distinct database_name from ##all_tables) dbs
LEFT JOIN ##all_tables tbls on tbls.database_name=dbs.database_name
WHERE dbs.database_name like '%' --PUT SOMETHING ELSE HERE
--This magic TSQL concatenates a column of values into a single string
--This string is then used in the dynamic pivoting below
DECLARE #dblist VARCHAR(MAX)
SELECT
#dblist = STUFF((SELECT ', [' + d_name + ']' AS [text()]
FROM (SELECT DISTINCT
database_name d_name
FROM ##tables_for_relevant_dbs) d
ORDER BY d_name
FOR XML PATH('')), 1, 1, '')
--Pivot the data to turn the database names into columns
EXEC ('SELECT ' + #dblist + '
FROM (SELECT at1.database_name, at2.table_name src, at1.table_name dest
FROM ##tables_for_relevant_dbs at1
LEFT JOIN ##tables_for_relevant_dbs at2 on at2.database_name=at1.database_name and at2.table_name=at1.table_name) t
PIVOT (max(t.src) FOR [database_name] IN (' + #dblist + ')) as [PVT]')
--Clean up
DROP TABLE ##all_tables
DROP TABLE ##tables_for_relevant_dbs
using common table expression to get table names in the information schema table and full outer join does the trick.
;with tables_in_DB1 as
(
select * from DB1.INFORMATION_SCHEMA.TABLES
where TABLE_TYPE='BASE TABLE'
),
tables_in_DB2 as
(
select * from DB2.INFORMATION_SCHEMA.TABLES
where TABLE_TYPE='BASE TABLE'
),
tables_in_DB3 as
(
select * from DB3.INFORMATION_SCHEMA.TABLES
where TABLE_TYPE='BASE TABLE'
)
select db1.table_name as DB2,db2.table_name as DB2,
db3.table_name as DB3 from tables_in_DB1 db1
full outer join tables_in_DB2 db2 on db1.TABLE_NAME=db2.TABLE_NAME
full outer join tables_in_DB3 db3 on db2.TABLE_NAME=db3.TABLE_NAME

Create Sql Server view using table name from sysobjects table

I have around 200 tables. I want to create a view from all these tables. I feel it is inefficient to hardcode all the table names and do an UNION ALL in the view definition.
Instead I am planning to retrieve the table name from sysobjects table like
Select name from sysobjects where name like 'Warehouse_Inventory%'
How can I use these table names and create a view out of it?
Note: I am selecting only 10 columns which are common. If any column is not present in a table, I want to display NULL for it.
This Query may help you..
SELECT 'CREATE VIEW VIEW_NAME AS'
UNION ALL
SELECT 'SELECT * FROM ['+NAME+']
UNION ALL' FROM SYS.TABLES where name like 'Warehouse_Inventory%'
I am not sure why you want to use sys.sysojects instead of other sys views. Also now sure why when you want to union all tables you would want to search by a table name..... I would probably recommend a cursor on tables and temp tables to hold your results if you have 200 tables just do to size of the query but if you really really want to do it via union all here is a way...
Build a list of the 10 columns you want. Then run the query. you may need to tweak and add some cast/convert function to ensure everything is the right datatypes this can be done dynamically with sys.types and sys.columns or just make sure everything is a NVARCHAR(???) by altering my dynamic sql below and move forward.
DECLARE #ListOfColumns AS TABLE (ColumnName VARCHAR(100))
INSERT INTO #ListOfColumns (ColumnName) VALUES ('col1'),('col2'),('col3')
DECLARE #SQLStatement NVARCHAR(MAX)
;WITH cteColumnsTableCross AS (
SELECT
SchemaName = s.name
,t.schema_id
,TableName = t.name
,l.ColumnName
FROm
#ListOfColumns l
CROSS JOIN sys.tables t
INNER JOIN sys.schemas s
ON t.schema_id = s.schema_id
)
, cteColumns AS (
SELECT
x.SchemaName
,x.TableName
,x.ColumnName
,ColumnExists = IIF(c.name IS NOT NULL,1,0)
,RowNum = ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY x.TableName DESC)
--you can add data type by getting from sys.columns and sys.types if desired
FROM
cteColumnsTableCross x
LEFT JOIN sys.tables t
ON x.TableName = t.name
AND x.schema_id = t.schema_id
LEFT JOIN sys.columns c
ON t.object_id = c.object_id
AND x.ColumnName = c.name
)
, cteSelectStatements AS (
SELECT
TableName = t.name
,TableSelect = 'SELECT TableName = ''' + t.name + ''', ' +
STUFF(
(SELECT ', ' + c.ColumnName + ' = ' + IIF(c.ColumnExists = 0,'NULL',c.ColumnName)
FROM
cteColumns c
WHERE t.name = c.Tablename
FOR XML PATH(''))
,1,1,'')
+ ' FROM ' + t.name +
IIF((ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY t.name DESC)) > 1,' UNION ALL ','')
FROM
sys.tables t
)
SELECT #SQLStatement = STUFF(
(SELECT ' ' + TableSelect
FROM
cteSelectStatements
ORDER BY
TableName
FOR XML PATH(''))
,1,1,'')
PRINT #SQLStatement
--EXECUTE #SQLStatement

Change Rows to Columns in SQL Server

I've been working on this query for an hour and half but I can't get it done,
First, this is my query:
SELECT
Questions, PossibleAnswer,
((COUNT(PossibleAnswer) + 0.0) / 10 ) * 100 AS Percentage
FROM
(SELECT
A.AnswerID, B.Questions, B.QuestionID, C.PossibleAnswer
FROM
TblSurveyCustomerAnswers A
INNER JOIN
TblSurveyQuestion B ON A.QuestionID = B.QuestionID
INNER JOIN
TblSurveyAnswer C ON A.AnswerID = C.AnswerID
WHERE
A.CustomerID = 1) AS SOURCE
GROUP BY
Questions, PossibleAnswer
The result is below:
Now, I want the rows for column name PossibleAnswer to be converted in columns, so I did a research and found the PIVOT command (I need dynamic since it's a possible answers field) and this is my code
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(PossibleAnswer)
FROM
(
SELECT DISTINCT X.*
FROM
(
SELECT Questions,PossibleAnswer, ((COUNT(PossibleAnswer) + 0.0) / 10 ) * 100 AS Percentage
FROM
(
SELECT A.AnswerID,B.Questions, B.QuestionID, C.PossibleAnswer
FROM TblSurveyCustomerAnswers A
INNER JOIN TblSurveyQuestion B
ON A.QuestionID = B.QuestionID
INNER JOIN TblSurveyAnswer C
ON A.AnswerID = C.AnswerID
WHERE A.CustomerID = 1
) AS SOURCE
GROUP BY Questions, PossibleAnswer
) X
) AS B
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
'SELECT Questions, ' + #ColumnName + '
FROM TblSurveyCustomerAnswers A
INNER JOIN TblSurveyQuestion B
ON A.QuestionID = B.QuestionID
PIVOT(Max(Questions)
FOR PossibleAnswer IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
And I can't get the pivot work, need help. I'm stuck. See this error:
In general for questions like these you should provide sample data, table definitions and expected output so people can take your script, fiddle with it and produce something that works. See How to post a T-SQL question on a public forum for one way to do this.
Since it is hard to look at a dynamic script, not having the table structures, and point at what your problem is, let me give you the following advice:
Instead of taking your big query that produces the output and form queries around that big query, first insert the output of that query into a temporary table. You can do this by placing an INTO #temp_table clause after the SELECT clause. This creates a new temporary table #temp_table containing the output of the query.
SELECT --your select columns
INTO #p_in -- creates a temporary table #p_in that contains the output
FROM --the rest of your query
Determine the pivot columns based on the newly created temporary table. It'll be a lot more conscise and easier to spot errors
Write your Dynamic SQL using the temporary table (again it'll be a lot more conscise and easier to spot errors)
Don't forget to DROP the temporary table after executing the dynamic SQL.
I just try to solved problem without temporary table. You may edit query as your requirement.
--For PIVOT column
DECLARE #ColumnName AS NVARCHAR(MAX)
SELECT #ColumnName ''''+ PossibleAnswer + '''' + ' , ' + #ColumnName
FROM
(
SELECT
DISTINCT PossibleAnswer
FROM
(
SELECT
A.AnswerID, B.Questions, B.QuestionID, C.PossibleAnswer
FROM
TblSurveyCustomerAnswers A
INNER JOIN
TblSurveyQuestion B ON A.QuestionID = B.QuestionID
INNER JOIN
TblSurveyAnswer C ON A.AnswerID = C.AnswerID
WHERE
A.CustomerID = 1
) AS SOURCE
)B
--For removing last comma
IF #ColumnName != ''
BEGIN
SET #ColumnName = SUBSTRING(#ColumnName, 1, LEN(#ColumnName)-1)
END
-- Make result
SELECT *
FROM
(
SELECT Questions,PossibleAnswer, ((COUNT(PossibleAnswer) + 0.0) / 10 ) * 100 AS Percentage
FROM
(
SELECT A.AnswerID,B.Questions, B.QuestionID, C.PossibleAnswer
FROM TblSurveyCustomerAnswers A
INNER JOIN TblSurveyQuestion B
ON A.QuestionID = B.QuestionID
INNER JOIN TblSurveyAnswer C
ON A.AnswerID = C.AnswerID
WHERE A.CustomerID = 1
) AS SOURCE
GROUP BY Questions, PossibleAnswer
)C
PIVOT
( Max(Questions)
FOR PossibleAnswer IN (#ColumnName)
) AS PVTTable

SQL - Query only the first 25 columns in that table

75 columns in a table - I want to query only the first 25 columns in that table without naming each column name.... can you assist with a SQL query....
I been playing with the following:
Select Table_Name, Count(*) As ColumnCount
From Information_Schema.Columns
Group By Table_Name
Order By Table_Name
Doesn't meet my output........
If a Table has 75 columns, How can I see the first 25 columns without naming each column name? Don't want to delete Columns Only want to see the first 25 columns out of 75 columns in the same table.....TOP is not enable need another work around....
First 25 columns in a table query built into #query and then executed. Substitute correct #target_table value.
DECLARE
#target_table sysname
, #query nvarchar(max)
SET
#target_table = '_dimAreaOverlay'
; with of_interest as
(
SELECT
SS.name AS schemaname
, T.name AS tablename
, SC.name AS columname
FROM
sys.schemas SS
inner join
sys.tables T
ON T.schema_id = SS.schema_id
inner join
sys.columns SC
ON SC.object_id = T.object_id
WHERE
T.name = #target_table
AND SC.column_id < 26
)
, c AS
(
SELECT
STUFF((
SELECT
',' + QUOTENAME(I.columname)
FROM
of_interest I
FOR XML PATH('')), 1,1, '') AS column_list
, OI.tablename
, OI.schemaname
FROM
of_interest OI
GROUP BY
OI.schemaname
, OI.tablename
)
SELECT
#query = 'SELECT '
+ C.column_list
+ ' FROM '
+ QUOTENAME(C.schemaname)
+ '.'
+ QUOTENAME(C.tablename)
FROM C
EXECUTE(#query)
Find the table in Management Studio Object Explorer.
Right click it and choose Script Table As -> Select To -> New Query Editor Window
Delete unwanted columns.