Pivot Using SQL Server 2000

Pivot using SQL Server 2000

We've successfully used the following approach in the past...

SELECT [p].ProductID,
[p].Name,
MAX(CASE [m].MetaKey
WHEN 'A'
THEN [m].MetaValue
END) AS A,
MAX(CASE [m].MetaKey
WHEN 'B'
THEN [m].MetaValue
END) AS B,
MAX(CASE [m].MetaKey
WHEN 'C'
THEN [m].MetaValue
END) AS C
FROM Products [p]
INNER JOIN ProductMeta [m]
ON [p].ProductId = [m].ProductId
GROUP BY [p].ProductID,
[p].Name

It can also be useful transposing aggregations with the use of...

SUM(CASE x WHEN 'y' THEN yVal ELSE 0 END) AS SUMYVal

EDIT

Also worth noting this is using ANSI standard SQL and so it will work across platforms :)

Sql server 2000 pivot query


Select Vessel
, Min ( Case When Month([Date]) = 1 Then Inspector End ) As Jan
, Min ( Case When Month([Date]) = 2 Then Inspector End ) As Feb
, Min ( Case When Month([Date]) = 3 Then Inspector End ) As Mar
...
, Min ( Case When Month([Date]) = 12 Then Inspector End ) As Dec
From Table
Group By Vessel

You have to statically declare the columns. It should be noted that this will only work for a single year. If what you are seeking is dynamic column (month) generation, then trying to do it in T-SQL is not the right approach as you can only do it with some fugly dynamic SQL. Instead, you should use a report generator or middle-tier component to build the result set.

How can I do a dynamic pivot in SQL Server 2000

We create SQL commands with the CASE statements from our application and fire them at the database (any database, not specifically SQL server). First we determine the number of pivot columns and their names using one query, from those results we generate the next query.
So the first query to determine the columns looks somewhat like:

SELECT DISTINCT myField FROM myTable

Then we use all the values in this result to construct an SQL command where a CASE statement is generated for each value.

We wanted a databasebase agnostic solution so we do this processing outside the database but i'm sure you could do the same in a stored procedure withing SQL server itself.

SQL 2000 Pivot for job timeline.

I managed to answer this myself so thought i would post in case anyone else needs

--

****************************************************************************************
-- This script returns a (graphical) timeline for all SQL jobs for use on SQL Server 2000
--****************************************************************************************
-- Version: 2.0
-- Author: Ryan Wooster
-- Date: 18-6-2013
--****************************************************************************************

set nocount on

declare @Minutes table (DT datetime)
--declare @JobNames table (JobName varchar(255))
declare @DT datetime
declare @StartDT varchar(20)
declare @EndDT varchar(20)
declare @Resolution int
declare @RemoveNonactiveJobs int
declare @IgnoreDisabledJobs int
declare @DSQLT varchar(4000)
declare @DSQL varchar(4000)
declare @Server varchar(20)
--***************************************************************************************
-- Set variables
--***************************************************************************************
set @StartDT = getdate() - 1
set @EndDT = getdate()
set @Resolution = 1 -- Enter the Resolution in minutes
set @RemoveNonactiveJobs = 1
set @IgnoreDisabledJobs = 1
set @Server = 'IGSQ03UK'
--***************************************************************************************
-- Pre-run cleanup (just in case)
--***************************************************************************************
IF OBJECT_ID('tempdb..#Timeline') IS NOT NULL DROP TABLE #Timeline;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
IF OBJECT_ID('tempdb..#Pivot') IS NOT NULL DROP TABLE #Pivot;
IF OBJECT_ID('tempdb..#tblTLine') IS NOT NULL DROP TABLE #tblTLine;
IF OBJECT_ID('tempdb..#tblTasks') IS NOT NULL DROP TABLE #tblTasks;
IF OBJECT_ID('tempdb..#JobNames') IS NOT NULL DROP TABLE #JobNames;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
--***************************************************************************************
--Create Temp Tables for use in Dynamic SQL
--***************************************************************************************
CREATE TABLE #JobNames (JobName varchar(128))
CREATE TABLE #Timeline (DT datetime, JobName varchar(128), Active int)
CREATE TABLE #JobRuntime (name varchar(128), SDT datetime, EDT datetime, DurationSeconds datetime)
--***************************************************************************************
-- Make a Jobname table
--***************************************************************************************
--'+ @IgnoreDisabledJobs +'
SET @DSQLT='
insert into #JobNames (JobName)
select replace(name, '' '', ''.'') --Replace spaces (they are invalid in XML based pivot lower in the code)
from '+ @Server +'.msdb.dbo.sysjobs
where enabled = 1
--WHERE NAME = ''<dbname>''
--WHERE NAME like ''%<partial dbname>%'''
--Print @DSQLT
EXEC (@DSQLT)
--***************************************************************************************
-- Genereate a Datetime table between StartDT and EndDT with x minute Resolution
--***************************************************************************************
set @DT = @StartDT

WHILE @DT < @EndDT
begin
insert into @Minutes (DT) values(@DT)

set @DT= dateadd(mi, @Resolution, @DT)
end

--***************************************************************************************
-- Create a timeline table by crossjoining the Datetime and Jobnames tables
--***************************************************************************************
insert into #Timeline
select DT, JobName, 0 as Active
from @Minutes cross join #JobNames

--***************************************************************************************
-- Create the Job Runtime information table
--***************************************************************************************
SET @DSQL=
'INSERT into #JobRuntime
select replace(name, '' '', ''.'') as name --Replace spaces (they are invalid in XML based pivot lower in the code)
--,step_id
--,step_name
,CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + '' '' + STUFF(STUFF(RIGHT(''000000'' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, '':''), 3, 0, '':''), 120) as SDT
,dateadd( s,
((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 ,
CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + '' '' + STUFF(STUFF(RIGHT(''000000'' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, '':''), 3, 0, '':''), 120)
) as EDT
--,CAST(STUFF(STUFF(REPLACE(STR(run_duration, 6), '' '', ''0''), 3, 0, '':''), 6, 0, '':'') AS time(0)) AS Duration
,((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 DurationSeconds

FROM '+ @Server +'.msdb.dbo.sysjobs job
left JOIN '+ @Server +'.msdb.dbo.sysjobhistory his
ON his.job_id = job.job_id

where CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + '' '' + STUFF(STUFF(RIGHT(''000000'' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, '':''), 3, 0, '':''), 120) between '''+ @StartDT +''' and '''+ @EndDT +'''
and job.name not in (''Database Mirroring Monitor Job'', ''<dbname>'')
and step_id = 0 -- step_id = 0 is the entrite job, step_id > 0 is actual step number
--and ((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 > 1 -- Ignore trivial runtimes
order by SDT'
EXEC (@DSQL)

--***************************************************************************************
-- Update the Timeline based on the the Job Runtime information table
--***************************************************************************************
update #Timeline
set Active = 1
from #Timeline inner join #JobRuntime
on JobName = name
and (
SDT between dt and dateadd(mi, @Resolution - 1, DT) -- Start point (added for Resolution support)
or
EDT between dt and dateadd(mi, @Resolution, DT) -- End point (added for Resolution support)
or
DT between SDT and EDT
)

--***************************************************************************************
-- Delete all jobs from the Timeline that that had no activity
--***************************************************************************************
if @RemoveNonactiveJobs = 1
delete
from #Timeline
where JobName in ( select Jobname
from #Timeline
group by Jobname
having sum(active) = 0 )

--***************************************************************************************
-- Build and Pivot the Timeline table
--***************************************************************************************
create table #Pivot (DT varchar(250) null, Name varchar(250) null, Active int null)
-- col1 = row, col2 = column, col3 = data


insert into #Pivot
select convert(varchar(250), DT, 120), JobName, Active
from #Timeline


--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DECLARE @SQL nvarchar(4000)
DECLARE @TaskName nvarchar(100)

SET NOCOUNT ON

CREATE TABLE #tblTLine (
[DT] varchar(200)
)

CREATE TABLE #tblTasks (
[Tasks] varchar(200)
)

INSERT INTO #tblTasks (
[Tasks]
)
select DISTINCT
Name
from #Pivot


INSERT INTO #tblTLine (
[DT]
)
select DISTINCT
[DT]
from #Pivot
ORDER BY DT
--WHERE Active = 1

-- Build Table
DECLARE cur CURSOR FOR

select DISTINCT
[Tasks]
from #tblTasks

OPEN cur

FETCH NEXT FROM cur INTO @TaskName

WHILE @@FETCH_STATUS = 0
BEGIN

SET @SQL = 'ALTER TABLE #tblTLine ADD [' + @TaskName + '] nchar(1) NULL'
EXEC (@SQL)

SET @SQL = ''

SET @SQL = 'UPDATE #tblTLine SET [' + @TaskName + '] = ''0'''
EXEC (@SQL)

FETCH NEXT FROM cur INTO @TaskName

END

CLOSE cur
DEALLOCATE cur

-- Update Table

DECLARE @SQLUpdate nvarchar(4000)
DECLARE @Time nvarchar(100)
DECLARE @Name nvarchar(100)
DECLARE @Active nchar(1)


DECLARE curUpdate CURSOR FOR

SELECT
[DT],
[Name],
[Active]
FROM #Pivot
WHERE Active = 1

OPEN curUpdate

FETCH NEXT FROM curUpdate INTO @Time, @Name, @Active

WHILE @@FETCH_STATUS = 0
BEGIN

SET @SQLUpdate = 'UPDATE #tblTLine SET [' + @Name + '] = ''1'' WHERE [DT] = ''' + @Time + ''''
EXEC (@SQLUpdate)

FETCH NEXT FROM curUpdate INTO @Time, @Name, @Active

END

CLOSE curUpdate
DEALLOCATE curUpdate


SET NOCOUNT OFF


--***************************************************************************************
-- Output the Timeline table
--***************************************************************************************
SELECT * FROM #tblTLine

--***************************************************************************************
-- Cleanup
--***************************************************************************************
IF OBJECT_ID('tempdb..#Timeline') IS NOT NULL DROP TABLE #Timeline;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
IF OBJECT_ID('tempdb..#Pivot') IS NOT NULL DROP TABLE #Pivot;
IF OBJECT_ID('tempdb..#tblTLine') IS NOT NULL DROP TABLE #tblTLine;
IF OBJECT_ID('tempdb..#tblTasks') IS NOT NULL DROP TABLE #tblTasks;
IF OBJECT_ID('tempdb..#JobNames') IS NOT NULL DROP TABLE #JobNames;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SQL Server 2000: Pivot with conditions

In SQL Server 2000 there are not so many options available. You can use UNION ALL for this:

SELECT 'a' AS type, a
FROM mytable
WHERE a IS NOT NULL AND a <> 'NA'

UNION ALL

SELECT 'b' AS type, b
FROM mytable
WHERE b IS NOT NULL AND b <> 'NA'

UNION ALL

SELECT 'c' AS type, c
FROM mytable
WHERE c IS NOT NULL AND c <> 'NA'

UNION ALL

SELECT 'd' AS type, d
FROM mytable
WHERE d IS NOT NULL AND d <> 'NA'

Rows to Columns in SQL Server 2000

Since SQL Server 2000 does not have the PIVOT function, you should be able to use something similar to the following:

DECLARE @query AS NVARCHAR(4000)
DECLARE @rowCount as int
DECLARE @pivotCount as int
DECLARE @pivotRow as varchar(10)

set @rowCount = 1
set @pivotRow = ''

create table #colsPivot
(
id int IDENTITY(1,1),
name varchar(20),
CustId int
)

insert into #colsPivot
select 'Observacion', IDObservacionCustomer
from yourtable

set @pivotCount= (select COUNT(*) from #colsPivot)

-- reset rowcount
set @rowCount = 1
set @query = ''

---- create the CASE string
while @rowCount <= @pivotCount
begin
set @pivotRow = (select Top 1 CustId from #colsPivot)

set @query = @query + ', max(case when IDObservacionCustomer = ''' + @pivotRow + ''' then Observacion end) as ''Observacion_' + cast(@rowCount as varchar(10)) + ''''

delete from #colsPivot where CustId = @pivotRow

if @rowCount <= @pivotCount
begin
set @rowCount = @rowCount + 1
end
end

-- add the rest of the SQL Statement
set @query = 'SELECT IDProspecto ' + @query + ' from yourtable group by IDProspecto'

exec(@query)

See SQL Fiddle With Demo

SQL Server 2000 pivot without temporary tables?

I think you may be a bit confused as to what temporary tables are.

You should be able to create a temp table (in memory) within your SQL statement. No extra permissions are necessary.



Related Topics



Leave a reply



Submit