Select unique column names from a list of joined tables - sql
I have a list of tables that can be joined together by the same PK column. Since this list of tables can vary from project to project, I want to create a query that can be dynamic enough to pull all unique columns from these tables.
For example, I have three tables below:
Table A (PK field, column1, column 2)
Table B (PK field, column3, column 4)
Table C (PK field, column5, column 5)
These three tables are joined on "PK field" column, and I want the query output to be something like:
PK field column1 column2 column3 column4 column5
..data.. ..data.. ..data.. ..data.. ..data.. ..data..
At the end, this query will be part of a SQL function or SP, so the user can define a list of tables, and PK field at the beginning, then executing it shall return my expected output with dataset.
I think about use this query below but the result is not what I like:
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ''
Any advice about how I should design this SP or function, will be appreciated.
Thanks in advance.
DDL for two example tables:
CREATE TABLE [dbo].[G_bDEM](
[blaiseKey_code] [nvarchar](255) NULL,
[qSex] [int] NULL,
[qDOB] [datetime] NULL,
[qDOBNR] [int] NULL,
[qAge] [int] NULL,
[qAgeNR] [int] NULL,
[qAgeRange] [int] NULL,
[qAge15OrOver] [int] NULL,
[qNotEligible] [nvarchar](1) NULL,
[qBornInNZ] [int] NULL,
[qCountryOfBirth] [nvarchar](2) NULL,
[qArriveNZYr] [int] NULL,
[qArriveNZYrNR] [int] NULL,
[qArriveNZMth] [int] NULL,
[bDEM_BOP_qHowManyRaised] [int] NULL,
[bDEM_BOP_q1stParentBornNZ] [int] NULL,
[bDEM_BOP_q2ndParentBornNZ] [int] NULL,
[bDEM_BOP_qHowManyParentBornNZ] [int] NULL,
[qMaoriDescent] [int] NULL,
[qSchQual] [int] NULL,
[qSchQualOth] [nvarchar](200) NULL,
[qSchQualOthNR] [int] NULL,
[qSchQualYr] [int] NULL,
[qSchQualYrNR] [int] NULL,
[qPostSchQual] [int] NULL,
[q3MthsStudy] [int] NULL,
[qHighestQual] [int] NULL,
[qHighestQualOth] [nvarchar](200) NULL,
[qHighestQualOthNR] [int] NULL,
[qHighestQualYr] [int] NULL,
[qHighestQualYrNR] [int] NULL,
[qWorkIntro] [nvarchar](1) NULL,
[qDidPaidWork] [int] NULL,
[qAwayFromWork] [int] NULL,
[qFamilyBusWork] [int] NULL,
[bDEM_WOR_qPaidWorkIntro] [nvarchar](1) NULL,
[bDEM_WOR_qJobsNum] [int] NULL,
[bDEM_WOR_qJobsNumNR] [int] NULL,
[bDEM_WOR_tabDEM_T2_fTotMins] [int] NULL,
[bDEM_WOR_q2JobsNoHrsIntro] [nvarchar](1) NULL,
[bDEM_WOR_q2Jobs2HrsIntro] [nvarchar](1) NULL,
[bDEM_WOR_q2Jobs1HrsIntro] [nvarchar](1) NULL,
[bDEM_WOR_qOccupation] [nvarchar](200) NULL,
[bDEM_WOR_qOccupationNR] [int] NULL,
[bDEM_WOR_qMainTasks] [nvarchar](200) NULL,
[bDEM_WOR_qMainTasksNR] [int] NULL,
[bDEM_WOR_qFeelAboutJob] [int] NULL,
[bDEM_WOR_qEmployArrangement] [int] NULL,
[bDEM_WOR_qPermEmployee] [int] NULL,
[qHasJobToStart] [int] NULL,
[qLookedForWork] [int] NULL,
[qJobSearchA] [int] NULL,
[qJobSearchB] [int] NULL,
[qJobSearchC] [int] NULL,
[qJobSearchD] [int] NULL,
[qJobSearchE] [int] NULL,
[qJobSearchF] [int] NULL,
[qJobSearchG] [int] NULL,
[qJobSearchH] [int] NULL,
[qJobSearchI] [int] NULL,
[qJobSearchOth] [nvarchar](200) NULL,
[qJobSearchOthNR] [int] NULL,
[qCouldStartLastWk] [int] NULL,
[qIncTotalAmt] [int] NULL,
[fCountryName] [nvarchar](60) NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[G_bLWW](
[blaiseKey_code] [nvarchar](255) NULL,
[qThingsWorthwhileScale] [int] NULL
) ON [PRIMARY]
This script generate dynamic SQL for any table with similar PK name.
Query:
SET NOCOUNT ON
IF OBJECT_ID (N'dbo.A') IS NOT NULL
DROP TABLE dbo.A
IF OBJECT_ID (N'dbo.B') IS NOT NULL
DROP TABLE dbo.B
IF OBJECT_ID (N'dbo.C') IS NOT NULL
DROP TABLE dbo.C
CREATE TABLE dbo.A (PK_field INT PRIMARY KEY, column1 INT, column2 INT)
CREATE TABLE dbo.B (PK_field INT PRIMARY KEY, column3 INT, column4 INT)
CREATE TABLE dbo.C (PK_field INT PRIMARY KEY, column5 INT, [column 6] INT)
INSERT INTO dbo.A (PK_field, column1, column2)
VALUES (1, 1, 2), (2, 1, 2)
INSERT INTO dbo.B (PK_field, column3, column4)
VALUES (2, 3, 4)
INSERT INTO dbo.C (PK_field, column5, [column 6])
VALUES (1, 5, 6), (3, 5, 6)
DECLARE #SQL NVARCHAR(MAX)
;WITH cte AS
(
SELECT
column_name = '[' + c.name + ']'
, table_name = '[' + s.name + '].[' + o.name + ']'
FROM sys.columns c WITH (NOLOCK)
JOIN sys.objects o WITH (NOLOCK) ON c.[object_id] = o.[object_id]
JOIN sys.schemas s WITH (NOLOCK) ON o.[schema_id] = s.[schema_id]
WHERE o.name IN ('A', 'B', 'C')
AND s.name = 'dbo'
AND o.[type] = 'U'
), unicol AS (
SELECT TOP 1 column_name
FROM cte
GROUP BY cte.column_name
HAVING COUNT(cte.column_name) > 1
), cols AS
(
SELECT DISTINCT column_name
FROM cte
), tbl AS
(
SELECT DISTINCT table_name
FROM cte
), rs AS
(
SELECT
tbl.table_name
, column_name = ISNULL(cte.column_name, cols.column_name + ' = NULL')
FROM cols
CROSS JOIN tbl
LEFT JOIN cte ON cols.column_name = cte.column_name AND cte.table_name = tbl.table_name
), rs2 AS (
SELECT uni = ' UNION ALL' + CHAR(13) + 'SELECT ' + STUFF((
SELECT ', ' + rs.column_name
FROM rs
WHERE tbl.table_name = rs.table_name
GROUP BY rs.column_name
ORDER BY rs.column_name
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '') +
' FROM ' + table_name
FROM tbl
)
SELECT #SQL = 'SELECT
' + STUFF((
SELECT CHAR(13) + ', ' + ISNULL(unicol.column_name, cols.column_name + ' = MAX(' + cols.column_name + ')')
FROM cols
LEFT JOIN unicol ON cols.column_name = unicol.column_name
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, ' ')
+ '
FROM
(' + STUFF((
SELECT CHAR(10) + uni
FROM rs2
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 11, '') + CHAR(13) +
') t
GROUP BY ' + (SELECT column_name FROM unicol)
PRINT #SQL
EXECUTE sys.sp_executesql #SQL
Output:
SELECT
[column 6] = MAX([column 6])
, [column1] = MAX([column1])
, [column2] = MAX([column2])
, [column3] = MAX([column3])
, [column4] = MAX([column4])
, [column5] = MAX([column5])
, [PK_field]
FROM (
SELECT [column 6] = NULL, [column1], [column2], [column3] = NULL, [column4] = NULL, [column5] = NULL, [PK_field] FROM [dbo].[A]
UNION ALL
SELECT [column 6] = NULL, [column1] = NULL, [column2] = NULL, [column3], [column4], [column5] = NULL, [PK_field] FROM [dbo].[B]
UNION ALL
SELECT [column 6], [column1] = NULL, [column2] = NULL, [column3] = NULL, [column4] = NULL, [column5], [PK_field] FROM [dbo].[C]
) t
GROUP BY [PK_field]
Results:
column 6 column1 column2 column3 column4 column5 PK_field
----------- ----------- ----------- ----------- ----------- ----------- -----------
6 1 2 NULL NULL 5 1
NULL 1 2 3 4 NULL 2
6 NULL NULL NULL NULL 5 3
Update in script:
DECLARE #SQL NVARCHAR(2000) -> NVARCHAR(MAX)
Output for your DDL:
SELECT
[blaiseKey_code]
, [bDEM_BOP_q1stParentBornNZ] = MAX([bDEM_BOP_q1stParentBornNZ])
, [bDEM_BOP_q2ndParentBornNZ] = MAX([bDEM_BOP_q2ndParentBornNZ])
, [bDEM_BOP_qHowManyParentBornNZ] = MAX([bDEM_BOP_qHowManyParentBornNZ])
, [bDEM_BOP_qHowManyRaised] = MAX([bDEM_BOP_qHowManyRaised])
, [bDEM_WOR_q2Jobs1HrsIntro] = MAX([bDEM_WOR_q2Jobs1HrsIntro])
, [bDEM_WOR_q2Jobs2HrsIntro] = MAX([bDEM_WOR_q2Jobs2HrsIntro])
, [bDEM_WOR_q2JobsNoHrsIntro] = MAX([bDEM_WOR_q2JobsNoHrsIntro])
, [bDEM_WOR_qEmployArrangement] = MAX([bDEM_WOR_qEmployArrangement])
, [bDEM_WOR_qFeelAboutJob] = MAX([bDEM_WOR_qFeelAboutJob])
, [bDEM_WOR_qJobsNum] = MAX([bDEM_WOR_qJobsNum])
, [bDEM_WOR_qJobsNumNR] = MAX([bDEM_WOR_qJobsNumNR])
, [bDEM_WOR_qMainTasks] = MAX([bDEM_WOR_qMainTasks])
, [bDEM_WOR_qMainTasksNR] = MAX([bDEM_WOR_qMainTasksNR])
, [bDEM_WOR_qOccupation] = MAX([bDEM_WOR_qOccupation])
, [bDEM_WOR_qOccupationNR] = MAX([bDEM_WOR_qOccupationNR])
, [bDEM_WOR_qPaidWorkIntro] = MAX([bDEM_WOR_qPaidWorkIntro])
, [bDEM_WOR_qPermEmployee] = MAX([bDEM_WOR_qPermEmployee])
, [bDEM_WOR_tabDEM_T2_fTotMins] = MAX([bDEM_WOR_tabDEM_T2_fTotMins])
, [fCountryName] = MAX([fCountryName])
, [q3MthsStudy] = MAX([q3MthsStudy])
, [qAge] = MAX([qAge])
, [qAge15OrOver] = MAX([qAge15OrOver])
, [qAgeNR] = MAX([qAgeNR])
, [qAgeRange] = MAX([qAgeRange])
, [qArriveNZMth] = MAX([qArriveNZMth])
, [qArriveNZYr] = MAX([qArriveNZYr])
, [qArriveNZYrNR] = MAX([qArriveNZYrNR])
, [qAwayFromWork] = MAX([qAwayFromWork])
, [qBornInNZ] = MAX([qBornInNZ])
, [qCouldStartLastWk] = MAX([qCouldStartLastWk])
, [qCountryOfBirth] = MAX([qCountryOfBirth])
, [qDidPaidWork] = MAX([qDidPaidWork])
, [qDOB] = MAX([qDOB])
, [qDOBNR] = MAX([qDOBNR])
, [qFamilyBusWork] = MAX([qFamilyBusWork])
, [qHasJobToStart] = MAX([qHasJobToStart])
, [qHighestQual] = MAX([qHighestQual])
, [qHighestQualOth] = MAX([qHighestQualOth])
, [qHighestQualOthNR] = MAX([qHighestQualOthNR])
, [qHighestQualYr] = MAX([qHighestQualYr])
, [qHighestQualYrNR] = MAX([qHighestQualYrNR])
, [qIncTotalAmt] = MAX([qIncTotalAmt])
, [qJobSearchA] = MAX([qJobSearchA])
, [qJobSearchB] = MAX([qJobSearchB])
, [qJobSearchC] = MAX([qJobSearchC])
, [qJobSearchD] = MAX([qJobSearchD])
, [qJobSearchE] = MAX([qJobSearchE])
, [qJobSearchF] = MAX([qJobSearchF])
, [qJobSearchG] = MAX([qJobSearchG])
, [qJobSearchH] = MAX([qJobSearchH])
, [qJobSearchI] = MAX([qJobSearchI])
, [qJobSearchOth] = MAX([qJobSearchOth])
, [qJobSearchOthNR] = MAX([qJobSearchOthNR])
, [qLookedForWork] = MAX([qLookedForWork])
, [qMaoriDescent] = MAX([qMaoriDescent])
, [qNotEligible] = MAX([qNotEligible])
, [qPostSchQual] = MAX([qPostSchQual])
, [qSchQual] = MAX([qSchQual])
, [qSchQualOth] = MAX([qSchQualOth])
, [qSchQualOthNR] = MAX([qSchQualOthNR])
, [qSchQualYr] = MAX([qSchQualYr])
, [qSchQualYrNR] = MAX([qSchQualYrNR])
, [qSex] = MAX([qSex])
, [qThingsWorthwhileScale] = MAX([qThingsWorthwhileScale])
, [qWorkIntro] = MAX([qWorkIntro])
FROM
(
SELECT [bDEM_BOP_q1stParentBornNZ], [bDEM_BOP_q2ndParentBornNZ], [bDEM_BOP_qHowManyParentBornNZ], [bDEM_BOP_qHowManyRaised], [bDEM_WOR_q2Jobs1HrsIntro], [bDEM_WOR_q2Jobs2HrsIntro], [bDEM_WOR_q2JobsNoHrsIntro], [bDEM_WOR_qEmployArrangement], [bDEM_WOR_qFeelAboutJob], [bDEM_WOR_qJobsNum], [bDEM_WOR_qJobsNumNR], [bDEM_WOR_qMainTasks], [bDEM_WOR_qMainTasksNR], [bDEM_WOR_qOccupation], [bDEM_WOR_qOccupationNR], [bDEM_WOR_qPaidWorkIntro], [bDEM_WOR_qPermEmployee], [bDEM_WOR_tabDEM_T2_fTotMins], [blaiseKey_code], [fCountryName], [q3MthsStudy], [qAge], [qAge15OrOver], [qAgeNR], [qAgeRange], [qArriveNZMth], [qArriveNZYr], [qArriveNZYrNR], [qAwayFromWork], [qBornInNZ], [qCouldStartLastWk], [qCountryOfBirth], [qDidPaidWork], [qDOB], [qDOBNR], [qFamilyBusWork], [qHasJobToStart], [qHighestQual], [qHighestQualOth], [qHighestQualOthNR], [qHighestQualYr], [qHighestQualYrNR], [qIncTotalAmt], [qJobSearchA], [qJobSearchB], [qJobSearchC], [qJobSearchD], [qJobSearchE], [qJobSearchF], [qJobSearchG], [qJobSearchH], [qJobSearchI], [qJobSearchOth], [qJobSearchOthNR], [qLookedForWork], [qMaoriDescent], [qNotEligible], [qPostSchQual], [qSchQual], [qSchQualOth], [qSchQualOthNR], [qSchQualYr], [qSchQualYrNR], [qSex], [qThingsWorthwhileScale] = NULL, [qWorkIntro] FROM [dbo].[G_bDEM]
UNION ALL
SELECT [bDEM_BOP_q1stParentBornNZ] = NULL, [bDEM_BOP_q2ndParentBornNZ] = NULL, [bDEM_BOP_qHowManyParentBornNZ] = NULL, [bDEM_BOP_qHowManyRaised] = NULL, [bDEM_WOR_q2Jobs1HrsIntro] = NULL, [bDEM_WOR_q2Jobs2HrsIntro] = NULL, [bDEM_WOR_q2JobsNoHrsIntro] = NULL, [bDEM_WOR_qEmployArrangement] = NULL, [bDEM_WOR_qFeelAboutJob] = NULL, [bDEM_WOR_qJobsNum] = NULL, [bDEM_WOR_qJobsNumNR] = NULL, [bDEM_WOR_qMainTasks] = NULL, [bDEM_WOR_qMainTasksNR] = NULL, [bDEM_WOR_qOccupation] = NULL, [bDEM_WOR_qOccupationNR] = NULL, [bDEM_WOR_qPaidWorkIntro] = NULL, [bDEM_WOR_qPermEmployee] = NULL, [bDEM_WOR_tabDEM_T2_fTotMins] = NULL, [blaiseKey_code], [fCountryName] = NULL, [q3MthsStudy] = NULL, [qAge] = NULL, [qAge15OrOver] = NULL, [qAgeNR] = NULL, [qAgeRange] = NULL, [qArriveNZMth] = NULL, [qArriveNZYr] = NULL, [qArriveNZYrNR] = NULL, [qAwayFromWork] = NULL, [qBornInNZ] = NULL, [qCouldStartLastWk] = NULL, [qCountryOfBirth] = NULL, [qDidPaidWork] = NULL, [qDOB] = NULL, [qDOBNR] = NULL, [qFamilyBusWork] = NULL, [qHasJobToStart] = NULL, [qHighestQual] = NULL, [qHighestQualOth] = NULL, [qHighestQualOthNR] = NULL, [qHighestQualYr] = NULL, [qHighestQualYrNR] = NULL, [qIncTotalAmt] = NULL, [qJobSearchA] = NULL, [qJobSearchB] = NULL, [qJobSearchC] = NULL, [qJobSearchD] = NULL, [qJobSearchE] = NULL, [qJobSearchF] = NULL, [qJobSearchG] = NULL, [qJobSearchH] = NULL, [qJobSearchI] = NULL, [qJobSearchOth] = NULL, [qJobSearchOthNR] = NULL, [qLookedForWork] = NULL, [qMaoriDescent] = NULL, [qNotEligible] = NULL, [qPostSchQual] = NULL, [qSchQual] = NULL, [qSchQualOth] = NULL, [qSchQualOthNR] = NULL, [qSchQualYr] = NULL, [qSchQualYrNR] = NULL, [qSex] = NULL, [qThingsWorthwhileScale], [qWorkIntro] = NULL FROM [dbo].[G_bLWW]
) t
GROUP BY [blaiseKey_code]
Try this :
DECLARE
#cols VARCHAR(MAX)
, #TableA VARCHAR(10)= 'TableA'
, #TableB VARCHAR(10)= 'TableB'
, #TableC VARCHAR(10)= 'TableC'
, #Pk VARCHAR(20)
SELECT
#cols = STUFF((
SELECT DISTINCT ', [' + c.column_name + ']'
FROM INFORMATION_SCHEMA.Columns c
WHERE c.table_name IN ( #TableA,#TableB,#TableC )
FOR XML PATH('')
), 1, 2, '');
SELECT #Pk = column_name
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND table_name = #TableA
DECLARE #query VARCHAR(1000)
SET #query = 'SELECT ' + #cols + ' FROM ' + #TableA + ' JOIN ' + #TableB
+ ' ON ' + #TableA + '.' + #Pk + '=' + #TableB + '.' + #Pk
+ ' JOIN ' + #TableC + ' ON ' + #TableB + '.' + #Pk + '=' + #TableC
+ '.' + #Pk
EXEC (#query)
Do not forget the warning about special html characters in column name given by #Gordon.
You can only do this as a stored procedure. A SQL query returns a specified set of columns, no more, no less. The only way to get a variable number of columns is using dynamic SQL. And, functions don't support dynamic SQL.
You would need to construct a SQL statement, concatenating the column names from INFORMATION_SCHEMA.Columns. Something like this:
declare #cols varchar(max);
select #cols = stuff((select distinct ', ['+c.column_name+']'
from INFORMATION_SCHEMA.Columns c
where c.table_name in (<list of tables here>)
for xml path ('')
), 1, 2, '');
This will not work for column names that have special html characters, such as '<', '>', or '&'.
You can then construct the full query statement and execute it, with exec() or sp_executesql().
An alternative approach would be to create a view that has all the joins and all the columns. Let the SQL optimizer determine the best execution path.
Related
Any other possible ways to make a join like this #parameterServerName.msdb.dbo.sysjobs?
Building this Proc that will check if the job is running on one server and will start other job on the other server. Problem that I have here is: I cannot make a join this way INNER JOIN #parameterServerName.msdb.dbo.sysjobs Is there a way that I can make this join, without writing a bunch of 'if' statements for each possible input. CREATE Proc [dbo].[JobCheckStarter] #JobToCheck sysname ,#CheckServer varchar(128) ,#JobToStart sysname ,#StartServer varchar(128) AS Begin SET NOCOUNT ON -- Create a temporary table to hold job info CREATE TABLE #JobCheck ( job_id UNIQUEIDENTIFIER NOT NULL, last_run_date INT NOT NULL, last_run_time INT NOT NULL, next_run_date INT NOT NULL, next_run_time INT NOT NULL, next_run_schedule_id INT NOT NULL, requested_to_run INT NOT NULL, -- BOOL request_source INT NOT NULL, request_source_id sysname COLLATE database_default NULL, running INT NOT NULL, -- BOOL current_step INT NOT NULL, current_retry_attempt INT NOT NULL, job_state INT NOT NULL ) CREATE TABLE #JobStart ( job_id UNIQUEIDENTIFIER NOT NULL, last_run_date INT NOT NULL, last_run_time INT NOT NULL, next_run_date INT NOT NULL, next_run_time INT NOT NULL, next_run_schedule_id INT NOT NULL, requested_to_run INT NOT NULL, -- BOOL request_source INT NOT NULL, request_source_id sysname COLLATE database_default NULL, running INT NOT NULL, -- BOOL current_step INT NOT NULL, current_retry_attempt INT NOT NULL, job_state INT NOT NULL ) IF #CheckServer = 'serverOne' Begin INSERT INTO #JobCheck EXEC serverOne.master.dbo.xp_sqlagent_enum_jobs 1,dbo END Else BEGIN INSERT INTO #JobCheck EXEC serverTwo.master.dbo.xp_sqlagent_enum_jobs 1,dbo End If #StartServer = 'serverOne' Begin INSERT INTO #JobStart EXEC serverOne.master.dbo.xp_sqlagent_enum_jobs 1,dbo END Else BEGIN INSERT INTO #JobStart EXEC serverTwo.master.dbo.xp_sqlagent_enum_jobs 1,dbo End if exists ( SELECT Running FROM #JobCheck J INNER JOIN #CheckServer.msdb.dbo.sysjobs SJ ON J.job_ID = SJ.job_ID WHERE [name] = #JobToCheck and J.running = 0 ) Begin if exists ( SELECT Running,* FROM #JobStart J INNER JOIN #StartServer.msdb.dbo.sysjobs SJ ON J.job_ID = SJ.job_ID WHERE [name] = #JobToStart and J.running = 0 ) BEGIN PRINT 'Starting job ''' + #JobToStart + ''''; EXEC #StartServer.msdb.dbo.sp_start_job #JobToStart; END Else BEGIN PRINT 'Cannot Start ''' + #JobToStart + ''' Because it is Already Running '; END END ELSE BEGIN PRINT 'Job ''' + #JobToCheck + ''' is Running '; END Drop TABLE #Job END GO Build a dynamic one and it works,Thanks everyone who helped :D Create Proc [dbo].[JobCheckStarter] #JobToCheck Varchar(250) ,#CheckServer varchar(128) ,#JobToStart Varchar(250) ,#StartServer varchar(128) AS Begin SET NOCOUNT ON Declare #Sql nVarchar(max) Declare #IFSql nvarchar(max) --Declare #JobToCheck varchar(200) --Declare #CheckServer varchar(200) --Declare #JobToStart varchar(200) --Declare #StartServer varchar(200) --Set #JobToCheck = '' --Set #CheckServer ='' --Set #JobToStart = '' --Set #StartServer ='' Set #Sql = ' CREATE TABLE #JobCheck ( job_id UNIQUEIDENTIFIER NOT NULL, last_run_date INT NOT NULL, last_run_time INT NOT NULL, next_run_date INT NOT NULL, next_run_time INT NOT NULL, next_run_schedule_id INT NOT NULL, requested_to_run INT NOT NULL, -- BOOL request_source INT NOT NULL, request_source_id sysname COLLATE database_default NULL, running INT NOT NULL, -- BOOL current_step INT NOT NULL, current_retry_attempt INT NOT NULL, job_state INT NOT NULL ) CREATE TABLE #JobStart ( job_id UNIQUEIDENTIFIER NOT NULL, last_run_date INT NOT NULL, last_run_time INT NOT NULL, next_run_date INT NOT NULL, next_run_time INT NOT NULL, next_run_schedule_id INT NOT NULL, requested_to_run INT NOT NULL, -- BOOL request_source INT NOT NULL, request_source_id sysname COLLATE database_default NULL, running INT NOT NULL, -- BOOL current_step INT NOT NULL, current_retry_attempt INT NOT NULL, job_state INT NOT NULL ) INSERT INTO #JobCheck EXEC '+#CheckServer+'.master.dbo.xp_sqlagent_enum_jobs 1,dbo; INSERT INTO #JobStart EXEC '+#StartServer+'.master.dbo.xp_sqlagent_enum_jobs 1,dbo; ' Set #ifSQL = 'if exists ( SELECT Running FROM #JobCheck J INNER JOIN '+ #CheckServer+ '.msdb.dbo.sysjobs SJ ON J.job_ID = SJ.job_ID WHERE SJ.name = '+'''' +#JobToCheck+ '''' +' and J.running = 0 ) Begin if exists ( SELECT Running FROM #JobStart J INNER JOIN '+#StartServer+ '.msdb.dbo.sysjobs SJ ON J.job_ID = SJ.job_ID WHERE SJ.name = ' +''''+#JobToStart+''''+' and J.running = 0 )'+' BEGIN PRINT '+ '''Starting job ''' +'+'+ ''''+#JobToStart+''''+';'+ ' Exec '+ #StartServer+'.msdb.dbo.sp_start_job '+''''+ #JobToStart +'''' +' END Else BEGIN PRINT '+'''Cannot Start ''' +'+'+ ''''+#JobToStart+'''' +'+'+ ''' Because it is Already Running ''' +' END END ELSE BEGIN PRINT '+ '''Job ''' +'+'+ ''''+#JobToCheck+'''' +'+'+ ''' is Running ''' +' END ' Set #Sql= #Sql+#IFSql --print #sql --EXECUTE sp_executesql #Sql EXEC sp_executesql #Sql, N' #JobToCheck Varchar(250),#CheckServer varchar(128),#JobToStart Varchar(250),#StartServer varchar(128)',#JobToCheck ,#CheckServer,#JobToStart ,#StartServer END GO
SQL Server: set multiple values assigning them default
SET #StartDate = NULL, #InitialLoopValue=NULL, #FinalLoopValue = NULL, #RootId = NULL, #MakeId = NULL, #CityId = NULL, #CountOfCarsUpdated = NULL, #Url = NULL, #MakeName = NULL, #RootName = NULL, #CityName = NULL, #Content = NULL, #SellInquiryId = NULL, #SellerType = NULL,#imei = NULL; I have these many variables, and I get this error. But when I put SET individually for each default assignment its working fine but that's too verbose. How do I correct this?
You could use SELECT to assign multiple variables at once. SELECT #StartDate = NULL, #InitialLoopValue=NULL, #FinalLoopValue = NULL, #RootId = NULL, #MakeId = NULL, #CityId = NULL, #CountOfCarsUpdated = NULL, #Url = NULL, #MakeName = NULL, #RootName = NULL, #CityName = NULL, #Content = NULL, #SellInquiryId = NULL, #SellerType = NULL,#imei = NULL; Note: Default value for non-assigned variable is NULL so there is no need for = NULL. DECLARE #v INT; SELECT #v -- NULL
Slow Stored Procedure In ASP.NET But Fast In SSMS
I have stored procedure with runs fast in SQL Management Studio but it is 10 times slower in ASP.NET application. What is the reason of this strange behaviour and idea to fix it ? This is my Stored Procedure: Create procedure [dbo].[CRFarmersGet] #Company NVARCHAR(200) = NULL, #FName NVARCHAR(50) = NULL, #SName NVARCHAR(50) = NULL, #LName NVARCHAR(50) = NULL, #PID NVARCHAR(50) = NULL, #RegProvince NVARCHAR(50) = NULL, #RegCity NVARCHAR(50) = NULL, #ActCity NVARCHAR(50) = NULL, #ActCommune NVARCHAR(50) = NULL, #ActProvince NVARCHAR(50) = NULL, #SCATTUAct NVARCHAR(50) = NULL, #Culture NVARCHAR(50) = NULL, #CultureCode NVARCHAR(50) = NULL, #Contracts SMALLINT = 0 WITH ENCRYPTION As BEGIN SET #Company = NULLIF(RTRIM(LTRIM(#Company)), '') SET #FName = NULLIF(RTRIM(LTRIM(#FName)), '') SET #SName = NULLIF(RTRIM(LTRIM(#SName)), '') SET #LName = NULLIF(RTRIM(LTRIM(#LName)), '') SET #PID = NULLIF(RTRIM(LTRIM(#PID)), '') SET #RegProvince = NULLIF(RTRIM(LTRIM(#RegProvince)), '') SET #RegCity = NULLIF(RTRIM(LTRIM(#RegCity)), '') SET #ActCity = NULLIF(RTRIM(LTRIM(#ActCity)), '') SET #ActCommune = NULLIF(RTRIM(LTRIM(#ActCommune)), '') SET #ActProvince = NULLIF(RTRIM(LTRIM(#ActProvince)), '') SET #SCATTUAct = NULLIF(RTRIM(LTRIM(#SCATTUAct)), '') SET #Culture = NULLIF(RTRIM(LTRIM(#Culture)), '') SET #CultureCode = NULLIF(RTRIM(LTRIM(#CultureCode)), '') select f.[ID] ,f.[PID] ,f.[PIDType] ,f.[DerecognitionDate] ,f.[Company] ,f.[FName] ,f.[SName] ,f.[LName] ,l.ProvinceID as RegProvinceID ,l.Province as RegProvince ,l.CommuneID as RegCommuneID ,l.Commune as RegCommune ,f.[RegCityID] ,l.City as RegCity ,f.[AddrReg] ,f.[Sync] ,f.[D_Modify] ,f.[U_Modify] ,f.[Version] from CRFarmersT f join (select CityID, City, c.CommuneID, Commune, m.ProvinceID, Province from CitiesT c join MunicipalitiesT m on c.CommuneID = m.CommuneID join ProvincesT pr on m.ProvinceID = pr.ProvinceID) l on l.CityID = f.RegCityID LEFT JOIN dbo.CRFarmersDetailsT AS cfdt ON cfdt.FarmerID = f.ID LEFT JOIN (select CityID, City, c.CommuneID, Commune, m.ProvinceID, Province from CitiesT c join MunicipalitiesT m on c.CommuneID = m.CommuneID join ProvincesT pr on m.ProvinceID = pr.ProvinceID) fdl on fdl.CityID = cfdt.ActCityID LEFT JOIN dbo.CRCultures AS cc ON cc.ID = cfdt.CultureID LEFT JOIN dbo.CRContracts AS cc2 ON cc2.FarmerDetailID = cfdt.ID where (f.Company like + '%' + rtrim(ltrim(#Company)) + '%' OR #Company IS NULL) AND (f.fName like + '%' + rtrim(ltrim(#FName)) + '%' OR #FName IS NULL) AND (f.SName like + '%' + rtrim(ltrim(#SName)) + '%' OR #SName IS NULL) AND (f.LName like + '%' + rtrim(ltrim(#LName)) + '%' OR #LName IS NULL) AND (f.PID like + '%' + rtrim(ltrim(#PID)) + '%' OR #PID IS NULL) AND (l.ProvinceID like + '%' + rtrim(ltrim(#RegProvince)) + '%' OR #RegProvince IS NULL) AND (l.City like + '%' + rtrim(ltrim(#RegCity)) + '%' OR #RegCity IS NULL) AND (fdl.City like + '%' + rtrim(ltrim(#ActCity)) + '%' OR #ActCity IS NULL) AND (fdl.Commune like + '%' + rtrim(ltrim(#ActCommune)) + '%' OR #ActCommune IS NULL) AND (fdl.Province like + '%' + rtrim(ltrim(#ActProvince)) + '%' OR #ActProvince IS NULL) AND (cfdt.[SCATTU-Activity] like + '%' + rtrim(ltrim(#SCATTUAct)) + '%' OR #SCATTUAct IS NULL) AND (cc.Name like + '%' + rtrim(ltrim(#Culture)) + '%' OR #Culture IS NULL) AND (cc.Code like + '%' + rtrim(ltrim(#CultureCode)) + '%' OR #CultureCode IS NULL) AND (#Contracts = 1 AND cc2.ID IS NOT NULL OR #Contracts = 0) AND exists(select 1 from dbo.UserRights('00000000-0000-0000-0000-000000000000') where RightID in (600, 601, 602, 612, 613)) GROUP BY f.[ID] ,f.[PID] ,f.[PIDType] ,f.[DerecognitionDate] ,f.[Company] ,f.[FName] ,f.[SName] ,f.[LName] ,l.ProvinceID ,l.Province ,l.CommuneID ,l.Commune ,f.[RegCityID] ,l.City ,f.[AddrReg] ,f.[Sync] ,f.[D_Modify] ,f.[U_Modify] ,f.[Version] Order By PID END Go
Probably SSMS and ASP.NET are using a different execution plan. One thing to try is to add a With Recompile as in: Create procedure [dbo].[CRFarmersGet] #Company NVARCHAR(200) = NULL, #FName NVARCHAR(50) = NULL, #SName NVARCHAR(50) = NULL, #LName NVARCHAR(50) = NULL, #PID NVARCHAR(50) = NULL, #RegProvince NVARCHAR(50) = NULL, #RegCity NVARCHAR(50) = NULL, #ActCity NVARCHAR(50) = NULL, #ActCommune NVARCHAR(50) = NULL, #ActProvince NVARCHAR(50) = NULL, #SCATTUAct NVARCHAR(50) = NULL, #Culture NVARCHAR(50) = NULL, #CultureCode NVARCHAR(50) = NULL, #Contracts SMALLINT = 0 WITH ENCRYPTION, RECOMPILE (I am not sure what the syntax is for having both Encryption and Recompile) Here is a related question and an interesting read
How to optimize SQL query performance using Row_Number() to operate on millions of records in SQL Server?
In my project, i am using the following query with paging mechanism using Row_Number() in SQL Server 2005 to fetch the records from database containing millions of records. When i execute this query it is taking almost 1:25+ seconds to fetch the results, i am unable to figure out where am i going wrong ? How can we optimize this query to bring the expected results in quick possible time, displaying n records on first page and fetching respective records as paging operation proceeds ? This is how we create table: CREATE TABLE [iftable] ( [sid] [float] DEFAULT (0) NOT NULL , [mid] [float] DEFAULT (0) NOT NULL , [bid] [float] DEFAULT (0) NOT NULL , [fid] [float] DEFAULT (0) NOT NULL , [fsid] [float] DEFAULT (0) NOT NULL , [ftep] [float] DEFAULT (0) NOT NULL , [mtid] [float] DEFAULT (0) NOT NULL , [mstr] [varchar] (1000) DEFAULT (' ') NOT NULL , [urblb] [image] NULL , [urcode] [float] DEFAULT (0) NOT NULL , [cdate] [datetime] DEFAULT (getdate()) NOT NULL , [ctime] [char] (9) DEFAULT (' ') NOT NULL , [olevel] [float] DEFAULT (0) NOT NULL, [cat] [varchar](30) DEFAULT (' ') NOT NULL, [ukey1] [varchar](30) DEFAULT (' ') NOT NULL, [ukey2] [varchar](30) DEFAULT (' ') NOT NULL, [vk] [varchar](30) DEFAULT (' ') NOT NULL, [scode] [float] DEFAULT (0) NOT NULL, [sty] [float] DEFAULT (0) NOT NULL, [extnsn] [varchar](10) DEFAULT ('') NOT NULL, [pkey] [varchar] (30) DEFAULT (' ') NOT NULL, [bexists] [smallint] DEFAULT (0) NOT NULL ) ON [PRIMARY] CREATE UNIQUE INDEX [iftablekey01] ON [iftable]([pkey], [sid], [mid]) ON [PRIMARY] GO //Select query over the table created DECLARE #Sid nvarchar(30) DECLARE #Bid nvarchar(30) DECLARE #Fid nvarchar(30) DECLARE #Stid nvarchar(30) DECLARE #QFid nvarchar(30) DECLARE #FromDate nvarchar(30) DECLARE #ToDate nvarchar(30) DECLARE #RFID nvarchar(30) DECLARE #FRID nvarchar(30) DECLARE #FsID nvarchar(30) DECLARE #Exclude nvarchar(MAX) DECLARE #ExecuteDSQL nvarchar(MAX) --Here below all the values will be coming from different variables like #QFid = 'VarQfid' SET #Sid = '' IF(#Sid = '*') SET #Sid = 'ALL' SET #Bid = '' IF(#Bid = '*') SET #Bid = 'ALL' SET #Fid = '' IF(#Fid = '*') SET #Fid = 'ALL' SET #Stid = '' IF(#Stid = '*') SET #Stid = 'ALL' SET #QFid = 'ALL' SET #FromDate = '' SET #ToDate = '' SET #RFID = '' SET #FRID = '' SET #FsID = '' SET #Exclude = '' IF(#Exclude = '') SET #Exclude = '100' SET #ExecuteDSQL = 'SELECT * FROM ( SELECT *, Row_Number() over(order by cdate desc,ctime desc,mid desc) as rowNum from iftable where pkey=''ABC''' + ' AND (cdate BETWEEN (CASE WHEN '''+#FromDate+''' =''0'' THEN ''1970-01-01'' WHEN '''+#FromDate+''' = '''' THEN ''1970-01-01'' ELSE ''ValueCameFromVariable'' END) AND (CASE WHEN '''+#ToDate+''' = ''0'' THEN ''5000-01-01'' WHEN '''+#ToDate+''' = '''' THEN ''5000-01-01'' ELSE ''ValueCameFromVariable'' END)) ' + ' AND (('''+#QFid+''' = ''ALL'' AND mtid IN (select mtid FROM iftable)) OR ('''+#QFid+''' = ''Err'' AND mtid IN(9,15)) OR ('''+#QFid+''' = ''CLog'' AND mtid IN(9,15,14,50,56))) ' + ' AND sid = (CASE WHEN '''+#Sid+''' = ''ALL'' THEN sid WHEN '''+#Sid+''' = '''' THEN sid ELSE '''+#Sid+''' END) ' + ' AND bid = (CASE WHEN '''+#Bid+''' = ''ALL'' THEN bid WHEN '''+#Bid+''' = '''' THEN bid ELSE '''+#Bid+''' END) ' + ' AND fid = (CASE WHEN '''+#Fid+''' = ''ALL'' THEN fid WHEN '''+#Fid+''' = '''' THEN fid ELSE '''+#Fid+''' END) ' + ' AND stid = (CASE WHEN '''+#Stid+''' = ''ALL'' THEN stid WHEN '''+#Stid+''' = '''' THEN stid ELSE '''+#Stid+''' END)' + ' AND rfid = (CASE WHEN '''+#RFID+''' = ''0'' THEN rfid WHEN '''+#RFID+''' = '''' THEN rfid ELSE '''+#RFID+''' END) ' + ' AND frid = (CASE WHEN '''+#FRID+''' = ''0'' THEN frid WHEN '''+#FRID+''' = '''' THEN frid ELSE '''+#FRID+''' END) ' + ' AND fsid = (CASE WHEN '''+#FsID+''' = ''0'' THEN fsid WHEN '''+#FsID+''' = '''' THEN fsid ELSE '''+#FsID+''' END)' + ' AND mtid NOT IN ('+#Exclude+')) AS newTable WHERE newTable.RowNum BETWEEN ''1'' AND ''50''' exec sp_executesql #ExecuteDSQL
The problem with your Query is you are sorting by cdate desc,ctime desc,mid but you dont have indexes by all the columns your are using to sort. You should create this index to improve your query: CREATE CLUSTERED INDEX [_dta_index_iftable_c_8_205243786__K11D_K12D_K2D] ON [dbo].[iftable] ( [cdate] DESC, [ctime] DESC, [mid] DESC )WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
Braking( split ) one row in multiples row
I have a database that works as a logbook for employees on SQL Server 2005. All of the information is filled up at the end of the month in one single table. It has check-in morning, check-out morning, check-in afternoon, check-out afternoon, and comment. As requested the structure of the table goes as follow: USE [BitacoraTrabajo] GO /****** Objeto: Table [dbo].[B_Bitacora] Fecha de la secuencia de comandos: 07/28/2014 10:25:25 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[B_Bitacora]( [BBIT_IdBitacora] [int] IDENTITY(1,1) NOT NULL, [BUSU_IdUsuario] [int] NOT NULL, [BBIT_Fecha] [datetime] NOT NULL, [BBIT_01ManEntra] [datetime] NULL, [BBIT_01ManSale] [datetime] NULL, [BBIT_01TarEntra] [datetime] NULL, [BBIT_01TarSale] [datetime] NULL, [BBIT_01Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_02ManEntra] [datetime] NULL, [BBIT_02ManSale] [datetime] NULL, [BBIT_02TarEntra] [datetime] NULL, [BBIT_02TarSale] [datetime] NULL, [BBIT_02Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_03ManEntra] [datetime] NULL, [BBIT_03ManSale] [datetime] NULL, [BBIT_03TarEntra] [datetime] NULL, [BBIT_03TarSale] [datetime] NULL, [BBIT_03Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_04ManEntra] [datetime] NULL, [BBIT_04ManSale] [datetime] NULL, [BBIT_04TarEntra] [datetime] NULL, [BBIT_04TarSale] [datetime] NULL, [BBIT_04Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_05ManEntra] [datetime] NULL, [BBIT_05ManSale] [datetime] NULL, [BBIT_05TarEntra] [datetime] NULL, [BBIT_05TarSale] [datetime] NULL, [BBIT_05Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_06ManEntra] [datetime] NULL, [BBIT_06ManSale] [datetime] NULL, [BBIT_06TarEntra] [datetime] NULL, [BBIT_06TarSale] [datetime] NULL, [BBIT_06Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_07ManEntra] [datetime] NULL, [BBIT_07ManSale] [datetime] NULL, [BBIT_07TarEntra] [datetime] NULL, [BBIT_07TarSale] [datetime] NULL, [BBIT_07Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_08ManEntra] [datetime] NULL, [BBIT_08ManSale] [datetime] NULL, [BBIT_08TarEntra] [datetime] NULL, [BBIT_08TarSale] [datetime] NULL, [BBIT_08Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_09ManEntra] [datetime] NULL, [BBIT_09ManSale] [datetime] NULL, [BBIT_09TarEntra] [datetime] NULL, [BBIT_09TarSale] [datetime] NULL, [BBIT_09Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_10ManEntra] [datetime] NULL, [BBIT_10ManSale] [datetime] NULL, [BBIT_10TarEntra] [datetime] NULL, [BBIT_10TarSale] [datetime] NULL, [BBIT_10Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_11ManEntra] [datetime] NULL, [BBIT_11ManSale] [datetime] NULL, [BBIT_11TarEntra] [datetime] NULL, [BBIT_11TarSale] [datetime] NULL, [BBIT_11Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_12ManEntra] [datetime] NULL, [BBIT_12ManSale] [datetime] NULL, [BBIT_12TarEntra] [datetime] NULL, [BBIT_12TarSale] [datetime] NULL, [BBIT_12Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_13ManEntra] [datetime] NULL, [BBIT_13ManSale] [datetime] NULL, [BBIT_13TarEntra] [datetime] NULL, [BBIT_13TarSale] [datetime] NULL, [BBIT_13Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_14ManEntra] [datetime] NULL, [BBIT_14ManSale] [datetime] NULL, [BBIT_14TarEntra] [datetime] NULL, [BBIT_14TarSale] [datetime] NULL, [BBIT_14Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_15ManEntra] [datetime] NULL, [BBIT_15ManSale] [datetime] NULL, [BBIT_15TarEntra] [datetime] NULL, [BBIT_15TarSale] [datetime] NULL, [BBIT_15Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_16ManEntra] [datetime] NULL, [BBIT_16ManSale] [datetime] NULL, [BBIT_16TarEntra] [datetime] NULL, [BBIT_16TarSale] [datetime] NULL, [BBIT_16Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_17ManEntra] [datetime] NULL, [BBIT_17ManSale] [datetime] NULL, [BBIT_17TarEntra] [datetime] NULL, [BBIT_17TarSale] [datetime] NULL, [BBIT_17Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_18ManEntra] [datetime] NULL, [BBIT_18ManSale] [datetime] NULL, [BBIT_18TarEntra] [datetime] NULL, [BBIT_18TarSale] [datetime] NULL, [BBIT_18Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_19ManEntra] [datetime] NULL, [BBIT_19ManSale] [datetime] NULL, [BBIT_19TarEntra] [datetime] NULL, [BBIT_19TarSale] [datetime] NULL, [BBIT_19Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_20ManEntra] [datetime] NULL, [BBIT_20ManSale] [datetime] NULL, [BBIT_20TarEntra] [datetime] NULL, [BBIT_20TarSale] [datetime] NULL, [BBIT_20Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_21ManEntra] [datetime] NULL, [BBIT_21ManSale] [datetime] NULL, [BBIT_21TarEntra] [datetime] NULL, [BBIT_21TarSale] [datetime] NULL, [BBIT_21Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_22ManEntra] [datetime] NULL, [BBIT_22ManSale] [datetime] NULL, [BBIT_22TarEntra] [datetime] NULL, [BBIT_22TarSale] [datetime] NULL, [BBIT_22Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_23ManEntra] [datetime] NULL, [BBIT_23ManSale] [datetime] NULL, [BBIT_23TarEntra] [datetime] NULL, [BBIT_23TarSale] [datetime] NULL, [BBIT_23Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_24ManEntra] [datetime] NULL, [BBIT_24ManSale] [datetime] NULL, [BBIT_24TarEntra] [datetime] NULL, [BBIT_24TarSale] [datetime] NULL, [BBIT_24Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_25ManEntra] [datetime] NULL, [BBIT_25ManSale] [datetime] NULL, [BBIT_25TarEntra] [datetime] NULL, [BBIT_25TarSale] [datetime] NULL, [BBIT_25Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_26ManEntra] [datetime] NULL, [BBIT_26ManSale] [datetime] NULL, [BBIT_26TarEntra] [datetime] NULL, [BBIT_26TarSale] [datetime] NULL, [BBIT_26Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_27ManEntra] [datetime] NULL, [BBIT_27ManSale] [datetime] NULL, [BBIT_27TarEntra] [datetime] NULL, [BBIT_27TarSale] [datetime] NULL, [BBIT_27Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_28ManEntra] [datetime] NULL, [BBIT_28ManSale] [datetime] NULL, [BBIT_28TarEntra] [datetime] NULL, [BBIT_28TarSale] [datetime] NULL, [BBIT_28Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_29ManEntra] [datetime] NULL, [BBIT_29ManSale] [datetime] NULL, [BBIT_29TarEntra] [datetime] NULL, [BBIT_29TarSale] [datetime] NULL, [BBIT_29Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_30ManEntra] [datetime] NULL, [BBIT_30ManSale] [datetime] NULL, [BBIT_30TarEntra] [datetime] NULL, [BBIT_30TarSale] [datetime] NULL, [BBIT_30Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, [BBIT_31ManEntra] [datetime] NULL, [BBIT_31ManSale] [datetime] NULL, [BBIT_31TarEntra] [datetime] NULL, [BBIT_31TarSale] [datetime] NULL, [BBIT_31Comentario] [varchar](100) COLLATE Modern_Spanish_CI_AS NULL, CONSTRAINT [PK_B_Bitacora] PRIMARY KEY CLUSTERED ( [BBIT_IdBitacora] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[B_Bitacora] WITH CHECK ADD CONSTRAINT [FK_B_Bitacora_B_Usuario] FOREIGN KEY([BUSU_IdUsuario]) REFERENCES [dbo].[B_Usuario] ([BUSU_IdUsuario]) GO ALTER TABLE [dbo].[B_Bitacora] CHECK CONSTRAINT [FK_B_Bitacora_B_Usuario] For each day I use a stored procedure to fill it up: EXEC #return_value = [dbo].[Sp_InsertBitacora] #BUSU_IdUsuario = 1416127, #BBIT_Fecha = '2014/22/06 00:00:00.000', #BBIT_01ManEntra = '2014/01/05 07:50:00.000', #BBIT_01ManSale = '2014/01/05 14:05:00.000', #BBIT_01TarEntra = '2014/01/05 15:55:00.000', #BBIT_01TarSale = '2014/01/05 19:10:00.000', #BBIT_01Comentario = null, #BBIT_02ManEntra = '2014/02/05 07:51:00.000', #BBIT_02ManSale = '2014/02/05 14:04:00.000', #BBIT_02TarEntra = '2014/02/05 15:50:00.000', #BBIT_02TarSale = '2014/02/05 19:20:00.000', #BBIT_02Comentario = null, #BBIT_03ManEntra = '2014/03/05 07:52:00.000', #BBIT_03ManSale = '2014/03/05 14:06:00.000', #BBIT_03TarEntra = '2014/03/05 15:57:00.000', #BBIT_03TarSale = '2014/03/05 19:11:00.000', #BBIT_03Comentario = null, #BBIT_04ManEntra = '2014/04/05 07:53:00.000', #BBIT_04ManSale = '2014/04/05 14:07:00.000', #BBIT_04TarEntra = '2014/04/05 15:58:00.000', #BBIT_04TarSale = '2014/04/05 19:13:00.000', #BBIT_04Comentario = null, #BBIT_05ManEntra = '2014/05/05 07:54:00.000', #BBIT_05ManSale = '2014/05/05 14:00:00.000', #BBIT_05TarEntra = '2014/05/05 15:59:00.000', #BBIT_05TarSale = '2014/05/05 19:14:00.000', #BBIT_05Comentario = null, #BBIT_06ManEntra = null, #BBIT_06ManSale = null, #BBIT_06TarEntra = null, #BBIT_06TarSale = null, #BBIT_06Comentario = 'Fin de Semana', #BBIT_07ManEntra = null, #BBIT_07ManSale = null, #BBIT_07TarEntra = null, #BBIT_07TarSale = null, #BBIT_07Comentario = 'Fin de Semana', #BBIT_08ManEntra = '2014/08/05 07:58:00.000', #BBIT_08ManSale = '2014/08/05 14:02:00.000', #BBIT_08TarEntra = '2014/08/05 15:58:00.000', #BBIT_08TarSale = '2014/08/05 19:18:00.000', #BBIT_08Comentario = null, #BBIT_09ManEntra = '2014/09/05 07:59:00.000', #BBIT_09ManSale = '2014/09/05 14:04:00.000', #BBIT_09TarEntra = '2014/09/05 15:54:00.000', #BBIT_09TarSale = '2014/09/05 19:19:00.000', #BBIT_09Comentario = null, #BBIT_10ManEntra = '2014/10/05 07:40:00.000', #BBIT_10ManSale = '2014/10/05 14:15:00.000', #BBIT_10TarEntra = '2014/10/05 15:45:00.000', #BBIT_10TarSale = '2014/10/05 19:20:00.000', #BBIT_10Comentario = null, #BBIT_11ManEntra = '2014/11/05 07:41:00.000', #BBIT_11ManSale = '2014/11/05 14:11:00.000', #BBIT_11TarEntra = '2014/11/05 15:46:00.000', #BBIT_11TarSale = '2014/11/05 19:21:00.000', #BBIT_11Comentario = null, #BBIT_12ManEntra = '2014/12/05 07:50:00.000', #BBIT_12ManSale = '2014/12/05 14:05:00.000', #BBIT_12TarEntra = '2014/12/05 15:55:00.000', #BBIT_12TarSale = '2014/12/05 19:10:00.000', #BBIT_12Comentario = null, #BBIT_13ManEntra = null, #BBIT_13ManSale = null, #BBIT_13TarEntra = null, #BBIT_13TarSale = null, #BBIT_13Comentario = 'Fin de Semana', #BBIT_14ManEntra = null, #BBIT_14ManSale = null, #BBIT_14TarEntra = null, #BBIT_14TarSale = null, #BBIT_14Comentario = 'Fin de Semana', #BBIT_15ManEntra = '2014/15/05 07:50:00.000', #BBIT_15ManSale = '2014/15/05 14:05:00.000', #BBIT_15TarEntra = '2014/15/05 15:55:00.000', #BBIT_15TarSale = '2014/15/05 19:10:00.000', #BBIT_15Comentario = null, #BBIT_16ManEntra = '2014/16/05 07:50:00.000', #BBIT_16ManSale = '2014/16/05 14:05:00.000', #BBIT_16TarEntra = '2014/16/05 15:55:00.000', #BBIT_16TarSale = '2014/16/05 19:10:00.000', #BBIT_16Comentario = null, #BBIT_17ManEntra = '2014/17/05 07:50:00.000', #BBIT_17ManSale = '2014/17/05 14:05:00.000', #BBIT_17TarEntra = '2014/17/05 15:55:00.000', #BBIT_17TarSale = '2014/17/05 19:10:00.000', #BBIT_17Comentario = null, #BBIT_18ManEntra = '2014/18/05 07:50:00.000', #BBIT_18ManSale = '2014/18/05 14:05:00.000', #BBIT_18TarEntra = '2014/18/05 15:55:00.000', #BBIT_18TarSale = '2014/18/05 19:10:00.000', #BBIT_18Comentario = null, #BBIT_19ManEntra = '2014/19/05 07:50:00.000', #BBIT_19ManSale = '2014/19/05 14:05:00.000', #BBIT_19TarEntra = '2014/19/05 15:55:00.000', #BBIT_19TarSale = '2014/19/05 19:10:00.000', #BBIT_19Comentario = null, #BBIT_20ManEntra = null, #BBIT_20ManSale = null, #BBIT_20TarEntra = null, #BBIT_20TarSale = null, #BBIT_20Comentario = 'Fin de Semana', #BBIT_21ManEntra = null, #BBIT_21ManSale = null, #BBIT_21TarEntra = null, #BBIT_21TarSale = null, #BBIT_21Comentario = 'Fin de Semana', #BBIT_22ManEntra = '2014/22/05 07:50:00.000', #BBIT_22ManSale = '2014/22/05 14:05:00.000', #BBIT_22TarEntra = '2014/22/05 15:55:00.000', #BBIT_22TarSale = '2014/22/05 19:10:00.000', #BBIT_22Comentario = null, #BBIT_23ManEntra = '2014/23/05 07:50:00.000', #BBIT_23ManSale = '2014/23/05 14:05:00.000', #BBIT_23TarEntra = '2014/23/05 15:55:00.000', #BBIT_23TarSale = '2014/23/05 19:10:00.000', #BBIT_23Comentario = null, #BBIT_24ManEntra = '2014/24/05 07:50:00.000', #BBIT_24ManSale = '2014/24/05 14:05:00.000', #BBIT_24TarEntra = '2014/24/05 15:55:00.000', #BBIT_24TarSale = '2014/24/05 19:10:00.000', #BBIT_24Comentario = null, #BBIT_25ManEntra = '2014/25/05 07:50:00.000', #BBIT_25ManSale = '2014/25/05 14:05:00.000', #BBIT_25TarEntra = '2014/25/05 15:55:00.000', #BBIT_25TarSale = '2014/25/05 19:10:00.000', #BBIT_25Comentario = null, #BBIT_26ManEntra = '2014/26/05 07:50:00.000', #BBIT_26ManSale = '2014/26/05 14:05:00.000', #BBIT_26TarEntra = '2014/26/05 15:55:00.000', #BBIT_26TarSale = '2014/26/05 19:10:00.000', #BBIT_26Comentario = null, #BBIT_27ManEntra = null, #BBIT_27ManSale = null, #BBIT_27TarEntra = null, #BBIT_27TarSale = null, #BBIT_27Comentario = 'Fin de Semana', #BBIT_28ManEntra = null, #BBIT_28ManSale = null, #BBIT_28TarEntra = null, #BBIT_28TarSale = null, #BBIT_28Comentario = 'Fin de Semana', #BBIT_29ManEntra = '2014/29/05 07:50:00.000', #BBIT_29ManSale = '2014/29/05 14:05:00.000', #BBIT_29TarEntra = '2014/29/05 15:55:00.000', #BBIT_29TarSale = '2014/29/05 19:10:00.000', #BBIT_29Comentario = null, #BBIT_30ManEntra = '2014/30/05 07:50:00.000', #BBIT_30ManSale = '2014/30/05 14:05:00.000', #BBIT_30TarEntra = '2014/30/05 15:55:00.000', #BBIT_30TarSale = '2014/30/05 19:10:00.000', #BBIT_30Comentario = null, #BBIT_31ManEntra = '2014/31/05 07:50:00.000', #BBIT_31ManSale = '2014/31/05 14:05:00.000', #BBIT_31TarEntra = '2014/31/05 15:55:00.000', #BBIT_31TarSale = '2014/31/05 19:10:00.000', #BBIT_31Comentario = null SELECT 'Return Value' = #return_value GO The problem is that I need to display this information in a specific format, one row for each day of the month: Day | CheckinMornig | CheckOutMonrning | CheckInAfternoon | CheckOutAfternoon | Comment 1 | 7:00 pm | 2:00 pm | 4:00 pm | 7:00 pm | none 2 | 7:05 pm | 1:50 pm | 3:55 pm | 7:10 pm | none 3 | null | null | null | null | weekend 4 | null | null | null | null | weekend ... 31 | 7:05 pm | 1:50 pm | 3:55 pm | 7:10 pm | none I tried to use UNION for each day: SELECT LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_01ManEntra, 100), 7)) as CheckInMorning ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_01ManSale, 100), 7)) as CheckOutMorning ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_01TarEntra, 100), 7)) as CheckInAfternoon ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_01TarSale, 100), 7)) as CheckOutAfternoon ,BBIT_01comentario as Comment FROM [BitacoraTrabajo].[dbo].[B_Bitacora] where BUSU_IdUsuario = 1416127 union SELECT LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_02ManEntra, 100), 7)) as CheckInMorning ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_02ManSale, 100), 7)) as CheckOutMorning ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_02TarEntra, 100), 7)) as CheckInAfternoon ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_02TarSale, 100), 7)) as CheckOutAfternoon ,BBIT_02comentario as Comment FROM [BitacoraTrabajo].[dbo].[B_Bitacora] where BUSU_IdUsuario = 1416127 but besides seeming like a very bad idea and a waste of resources, it doesn't work either, because it groups the days that have the same time and the weekends that have nulls. So, how to get a view or stored procedure with the format that I need?
You could try: DECLARE #USERID INT = 1416127 DECLARE #FECHA DATETIME = '2014-06-22' IF OBJECT_ID('dbo.TBL_DESTINATION', 'U') IS NOT NULL DROP TABLE dbo.TBL_DESTINATION DECLARE TABLE dbo.TBL_DESTINATION ( DAY INT, CheckInMorning datetime, CheckOutMorning datetime, CheckInAfternoon datetime, CheckOutAfternoon diatomite, Comentario VARCHAR(250) ) DECLARE #DAY INT = 1 DECLARE #SQL NVARCHAR(MAX) WHILE #DAY <= 31 BEGIN SET #SQL = 'INSERT INTO TBL_DESTINATION SELECT ' + CAST(#DAY as VARCHAR) + ', LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_' + case when #DAY < 10 then '0' + cast(#DAY as varchar) else cast(#DAY as varchar) end + 'ManEntra, 100), 7)) as CheckInMorning ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_' + case when #DAY < 10 then '0' + cast(#DAY as varchar) else cast(#DAY as varchar) end + 'ManSale, 100), 7)) as CheckOutMorning ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_' + case when #DAY < 10 then '0' + cast(#DAY as varchar) else cast(#DAY as varchar) end + 'TarEntra, 100), 7)) as CheckInAfternoon ,LTRIM(RIGHT(CONVERT(VARCHAR(20), BBIT_' + case when #DAY < 10 then '0' + cast(#DAY as varchar) else cast(#DAY as varchar) end + 'TarSale, 100), 7)) as CheckOutAfternoon ,BBIT_' + case when #DAY < 10 then '0' + cast(#DAY as varchar) else cast(#DAY as varchar) end + 'comentario as Comment FROM [BitacoraTrabajo].[dbo].[B_Bitacora] where BUSU_IdUsuario = ' + cast(#USERID as varchar) ' and BBIT_Fecha = ' + cast(#FECHA as varchar) EXECUTE sp_executesql #SQL SET #DAY = #DAY + 1 END SELECT * FROM dbo.TBL_DESTINATION You will certainly need to define date when the month was closed and the ID of the user who did it. You could create a procedure that would run this code and receive BUSU_IdUsuario and BBIT_Fecha values as parameters. It is up to you if you put this parameters in the SELECT of result of the query or not.