Friday, February 24, 2012
Crosstab in TSQL
temp table? I found several examples of stored procs to do this,
however they just produce results. I need to produce a table
to use to update another table.
Thanks much,
Marc MillerA simple one
USE pubs
GO
SELECT
stor_id,
SUM(CASE YEAR(ord_date)
WHEN 1992 THEN qty
ELSE 0
END) AS c1992,
SUM(CASE YEAR(ord_date)
WHEN 1993 THEN qty
ELSE 0
END) AS c1993,
SUM(CASE YEAR(ord_date)
WHEN 1994 THEN qty
ELSE 0
END) AS c1994
FROM Sales
GROUP BY stor_id
ORDER BY stor_id
"Marc Miller" <mm1284@.hotmail.com> wrote in message
news:ObOs2SzJGHA.1544@.TK2MSFTNGP11.phx.gbl...
> Does anyone know of any code to produce a crosstab table or
> temp table? I found several examples of stored procs to do this,
> however they just produce results. I need to produce a table
> to use to update another table.
> Thanks much,
> Marc Miller
>|||This article describes various techniques for implementing a crosstab type
query. Basically, it's just a group by query.
http://www.aspfaq.com/show.asp?id=2462
The result of any query can be output to a table or temporary table:
the SELECT.. INTO.. syntax will create a new table with the same column and
data type structure as the query result.
select
a,
b,
sum(cnt) as totcnt,
avg(cnt) as avgcnt
into
mycrosstab
from
mytable
group by
a,
b
the INSERT INTO.. SELECT.. syntax will insert the query result into an
existing table:
insert into mycrosstab
select
a,
b,
sum(cnt) as totcnt,
avg(cnt) as avgcnt
from
mytable
group by
a,
b
For temporary tables, just prefix the insert table with a # symbol.
insert into #mycrosstab . . .
"Marc Miller" <mm1284@.hotmail.com> wrote in message
news:ObOs2SzJGHA.1544@.TK2MSFTNGP11.phx.gbl...
> Does anyone know of any code to produce a crosstab table or
> temp table? I found several examples of stored procs to do this,
> however they just produce results. I need to produce a table
> to use to update another table.
> Thanks much,
> Marc Miller
>|||Uri,
Thanks! I took your suggestion a step further, becuase I the field names
can be variable. Here's what I did
(just for posterity I suppose, and anyone else trying to do the same.)
Temp table ##c_bt:
CUST_ACCT COLUMN_NAME AMOUNT
0123456 January 500.00
5464646 March 53.00
5161616 January 333.33
0123456 May 500.00
5464646 June 53.00
5161616 June 333.33
etc.
CODE:
DECLARE @.col varchar(20)
DECLARE @.DDL varchar(1000)
DECLARE curcols CURSOR
FOR select distinct column_name from ##c_bt order by column_name
OPEN curcols
SET @.DDL = 'Select cust_acct, '
FETCH NEXT FROM curcols INTO @.col
WHILE (@.@.fetch_status <> -1)
BEGIN
set @.DDL = @.DDL + ' SUM(CASE column_name WHEN ''' + rtrim(@.col) +''' THEN
amount ELSE 0 END) AS ' + rtrim(@.col) + ','
FETCH NEXT FROM curcols INTO @.col
END
CLOSE curcols
DEALLOCATE curcols
SET @.DDL = SUBSTRING(@.DDL,0,LEN(@.DDL)-1)
SET @.DDL = @.DDL + ' FROM ##c_bt GROUP BY cust_acct ORDER BY cust_acct'
EXEC(@.DDL)
Thanks again,
Marc
"Uri Dimant" <urid@.iscar.co.il> wrote in message
news:%23MG2$WzJGHA.1728@.TK2MSFTNGP14.phx.gbl...
>A simple one
> USE pubs
> GO
> SELECT
> stor_id,
> SUM(CASE YEAR(ord_date)
> WHEN 1992 THEN qty
> ELSE 0
> END) AS c1992,
> SUM(CASE YEAR(ord_date)
> WHEN 1993 THEN qty
> ELSE 0
> END) AS c1993,
> SUM(CASE YEAR(ord_date)
> WHEN 1994 THEN qty
> ELSE 0
> END) AS c1994
> FROM Sales
> GROUP BY stor_id
> ORDER BY stor_id
>
>
> "Marc Miller" <mm1284@.hotmail.com> wrote in message
> news:ObOs2SzJGHA.1544@.TK2MSFTNGP11.phx.gbl...
>|||Marc
Two questions I'd liek to ask you.
1) Why do you need to use a global temporary table?
2) Why do you need to use a cursor?
"Marc Miller" <mm1284@.hotmail.com> wrote in message
news:uLCuj6zJGHA.720@.TK2MSFTNGP14.phx.gbl...
> Uri,
> Thanks! I took your suggestion a step further, becuase I the field names
> can be variable. Here's what I did
> (just for posterity I suppose, and anyone else trying to do the same.)
> Temp table ##c_bt:
> CUST_ACCT COLUMN_NAME AMOUNT
> 0123456 January 500.00
> 5464646 March 53.00
> 5161616 January 333.33
> 0123456 May 500.00
> 5464646 June
> 53.00
> 5161616 June 333.33
> etc.
> CODE:
> DECLARE @.col varchar(20)
> DECLARE @.DDL varchar(1000)
> DECLARE curcols CURSOR
> FOR select distinct column_name from ##c_bt order by column_name
> OPEN curcols
> SET @.DDL = 'Select cust_acct, '
> FETCH NEXT FROM curcols INTO @.col
> WHILE (@.@.fetch_status <> -1)
> BEGIN
> set @.DDL = @.DDL + ' SUM(CASE column_name WHEN ''' + rtrim(@.col) +''' THEN
> amount ELSE 0 END) AS ' + rtrim(@.col) + ','
> FETCH NEXT FROM curcols INTO @.col
> END
> CLOSE curcols
> DEALLOCATE curcols
> SET @.DDL = SUBSTRING(@.DDL,0,LEN(@.DDL)-1)
> SET @.DDL = @.DDL + ' FROM ##c_bt GROUP BY cust_acct ORDER BY cust_acct'
> EXEC(@.DDL)
> Thanks again,
> Marc
>
> "Uri Dimant" <urid@.iscar.co.il> wrote in message
> news:%23MG2$WzJGHA.1728@.TK2MSFTNGP14.phx.gbl...
>|||Uri,
1) The temp table need not be global, it was just the way I was
experimenting, but I do need a table
to join and update another table.
2) I'm using the cursor to loop through its results to discover the 'column
names' that I need to build
my SQL. The column names can differ from month to month for me,
depending on the source data.
Marc
"Uri Dimant" <urid@.iscar.co.il> wrote in message
news:e7c5bC0JGHA.1032@.TK2MSFTNGP10.phx.gbl...
> Marc
> Two questions I'd liek to ask you.
> 1) Why do you need to use a global temporary table?
> 2) Why do you need to use a cursor?
>
> "Marc Miller" <mm1284@.hotmail.com> wrote in message
> news:uLCuj6zJGHA.720@.TK2MSFTNGP14.phx.gbl...
>|||Marc
> 1) The temp table need not be global, it was just the way I was
> experimenting, but I do need a table
> to join and update another table.
I don't see any reasons to use a global temrorary table. Pls refer to the
BOL for more details
> 2) I'm using the cursor to loop through its results to discover the
> 'column names' that I need to build
> my SQL. The column names can differ from month to month for me,
> depending on the source data.
>
Search on internet "dynamic crosstab" written by Itzik Ben-Gan
"Marc Miller" <mm1284@.hotmail.com> wrote in message
news:uvNydJ0JGHA.2864@.TK2MSFTNGP10.phx.gbl...
> Uri,
> 1) The temp table need not be global, it was just the way I was
> experimenting, but I do need a table
> to join and update another table.
> 2) I'm using the cursor to loop through its results to discover the
> 'column names' that I need to build
> my SQL. The column names can differ from month to month for me,
> depending on the source data.
> Marc
>
> "Uri Dimant" <urid@.iscar.co.il> wrote in message
> news:e7c5bC0JGHA.1032@.TK2MSFTNGP10.phx.gbl...
>|||Check out the RAC utility for pivoting/xtabs,
no coding necessary
www.rac4sql.net|||Is there an easy way, in outlook express, to stop this guy's spam from
showing up based on their alias?
I am sure that others use noname@.noname.com just to avoid being put on
mailing lists, and I don't want to filter out useful messages inadvertantly.
Thanks,
Jim
"05ponyGT" <noname@.noname.com> wrote in message
news:uN0pYl1JGHA.596@.TK2MSFTNGP10.phx.gbl...
> Check out the RAC utility for pivoting/xtabs,
> no coding necessary
> www.rac4sql.net
>|||Is that better:)
Have a nice day.
www.rac4sql.net
"Jim Underwood" <james.underwoodATfallonclinic.com> wrote in message
news:epx%23Ir1JGHA.1832@.TK2MSFTNGP11.phx.gbl...
> Is there an easy way, in outlook express, to stop this guy's spam from
> showing up based on their alias?
> I am sure that others use noname@.noname.com just to avoid being put on
> mailing lists, and I don't want to filter out useful messages
> inadvertantly.
> Thanks,
> Jim
> "05ponyGT" <noname@.noname.com> wrote in message
> news:uN0pYl1JGHA.596@.TK2MSFTNGP10.phx.gbl...
>
Thursday, February 16, 2012
Cross Referance dB objects accross store procs
Problem is: I need to know which tables and view from database01 are in use by store procedures in database02. This is important because if I accidently decommission tables that are currently in use by production class s-procedures, it will not be pretty. A sample output could look like:
StoreProc UsingObject
sp001 ctblCodeName
sp002 tblUnitSales
so003 tblSalesTrans
.......... .................
I am not a programmer and none of our programmers here claim that there is any solution to this problem without spending thousands on s/w licenses. Any simple solution + code snippet that will help me resolve this problem by myself would be incredibly valuable.
In disstress and frustration . . . .
JJOSHI
Hi JJOSHI,
There is no full-proof method of finding this information, though you could try a couple of things to get some pointers:
1) Check the sys.sql_dependencies catalog view for information (see books online for more information, if this is Sql 2005)
2) Try searching through the syscomments table (which is the table that holds the definition for all code modules in Sql)
Note that this doesn't capture references of things like foreign keys, constraints, etc....
There are some 3rd party components that try to give you this information, but MS doesn't guarantee this information, and supportability would be only through that company.
For searching through the syscomments, you could try something like this (NOT SUPPORTED IN ANY WAY BY ANYONE):
declare @.name varchar(500), @.sql varchar(1000)
select @.name = '%' + '<put object name here>' + '%'
-- Any jobs with it?
select j.name as JobName, s.step_name, s.command, s.database_name, j.enabled
from msdb.dbo.sysjobsteps s
join msdb.dbo.sysjobs j
on j.job_id = s.job_id
where command like(@.name)
-- Any db's reference it?
select @.sql = 'use [?] select object_name(id) as objectname, db_name() as dbname, substring(text, patindex(''' + @.name + ''', text) - 20,150) from syscomments where text like(''' + @.name + ''')'
exec master.dbo.sp_MSforeachdb @.sql
|||To add to what has already been said, in 2005, you can use the object_definition function. I had written a blog about this a while back (http://drsql.spaces.live.com/blog/cns!80677FB08B3162E4!1139.entry) to cover something like this. Since object_definition includes the whole object text in a single part (syscomments breaks it up into chunks in 2000) you can use a query like:
DECLARE @.value nvarchar(128)
SET @.value = '<databaseName>.'
SELECT cast(schema_name(schema_id) + '.' + name AS varchar(60)) AS name,
cast(type_desc AS varchar(20)) AS type , create_date,
modify_date,
char(13) + char(10)
+ '--select object_definition(' + cast(object_id as varchar(10)) + ') as [' + name + ']'
FROM sys.objects
WHERE charindex(@.value,replace(replace(object_definition(object_id),'[',''),']','')) > 0
The replaces get rid of brackets [] and then if you are looking for the database name plus the dot, you should find all references.
"This is important because if I accidently decommission tables that are currently in use by production class s-procedures, it will not be pretty."
I certainly hope you are planning on testing this first :) At the very least, you are demonstrating one great thing about susing all stored procedure access. Easy searching the code for references.