Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
MikeB
Constraint Violating Yak Guru
387 Posts |
Posted - 2005-02-23 : 11:10:35
|
How can I get a result set in the form of a cross tab without knowing the column names?tbEquipmentRentalfkItemID | fkCostID | Rate | Units---------------------------------------------1 | 21 | 45 | DAY1 | 23 | 400 | LSUM2 | 22 | 225 | DAY Notice that for fkItemID (1) there are 2 entries but for fkItemID (2) there is only 1 entry. When I select records for a certain itemI would like it to be in cross tab format:For item id (1)fkItemID | ID | Rate | Units | ID | Rate | Units------------------------------------------------1 | 21 | 45 | DAY | 23 | 400 | LSUMFor item id (2)fkItemID | ID | Rate | Units -------------------------------1 | 22 | 225 | DAY Is there any easy way to do this?Mike B |
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2005-02-23 : 13:56:46
|
Take a look here:http://www.sqlteam.com/item.asp?ItemID=2955But it won't really work for what you're describing, because you have a variable number of columns per group in the result set. This can't be done in SQL, you might be able to do something like it in a report though. |
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2005-02-23 : 14:08:30
|
This seems like a very odd requirement.You must use dynamic sql to solve this, here is one solution:create table #tbEquipmentRental(fkItemID int, fkCostID int, Rate int, Units char(4))insert #tbEquipmentRentalselect 1,21,45,'DAY' unionselect 1,23,400,'LSUM' unionselect 2,22,225,'DAY'declare @fkItemID intset @fkItemID = 1 --<---------------------------- put value of fkItemID heredeclare @sql varchar(8000)set @sql = 'select t.fkItemID' + char(10)select @sql = @sql + ' ,t'+ltrim(fkCostID)+'.fkCostID,t'+ltrim(fkCostID)+'.Rate,t'+ltrim(fkCostID)+'.Units' + char(10)from #tbEquipmentRental where fkItemID = @fkItemIDset @sql = @sql + 'from (select '+ltrim(@fkItemID)+' as fkItemID) t' + char(10)select @sql = @sql + ' ,#tbEquipmentRental t'+ltrim(fkCostID) + char(10)from #tbEquipmentRental where fkItemID = @fkItemIDset @sql = @sql + 'where 1 = 1' + char(10)select @sql = @sql + ' and t'+ltrim(fkCostID)+'.fkItemID = '+ltrim(@fkItemID)+' and t'+ltrim(fkCostID)+'.fkCostID = '+ltrim(fkCostID) + char(10)from #tbEquipmentRental where fkItemID = @fkItemID-- select @sqlexec(@sql)drop table #tbEquipmentRental rockmoose |
|
|
MikeB
Constraint Violating Yak Guru
387 Posts |
Posted - 2005-02-23 : 14:21:01
|
quote: Originally posted by rockmoose This seems like a very odd requirement.You must use dynamic sql to solve this, here is one solution:create table #tbEquipmentRental(fkItemID int, fkCostID int, Rate int, Units char(4))insert #tbEquipmentRentalselect 1,21,45,'DAY' unionselect 1,23,400,'LSUM' unionselect 2,22,225,'DAY'declare @fkItemID intset @fkItemID = 1 --<---------------------------- put value of fkItemID heredeclare @sql varchar(8000)set @sql = 'select t.fkItemID' + char(10)select @sql = @sql + ' ,t'+ltrim(fkCostID)+'.fkCostID,t'+ltrim(fkCostID)+'.Rate,t'+ltrim(fkCostID)+'.Units' + char(10)from #tbEquipmentRental where fkItemID = @fkItemIDset @sql = @sql + 'from (select '+ltrim(@fkItemID)+' as fkItemID) t' + char(10)select @sql = @sql + ' ,#tbEquipmentRental t'+ltrim(fkCostID) + char(10)from #tbEquipmentRental where fkItemID = @fkItemIDset @sql = @sql + 'where 1 = 1' + char(10)select @sql = @sql + ' and t'+ltrim(fkCostID)+'.fkItemID = '+ltrim(@fkItemID)+' and t'+ltrim(fkCostID)+'.fkCostID = '+ltrim(fkCostID) + char(10)from #tbEquipmentRental where fkItemID = @fkItemID-- select @sqlexec(@sql)drop table #tbEquipmentRental rockmoose
:)lol, it may be an odd requirment, I am full of them.The reason this is done is because for some equipment, some cost items are relavent and some aren't. For example, the fkItem 1 is crane rental. The fkCostID 21 = RENTAL and the fkCostID = MOVEINwhere as the fkItem 2 is trailer rental, where fkCostID = RENTAL, there is no "Movein" costs associated with it.I decided not to do it with the cross tab anyway. What I did was in the stored procedure for the update of a fkCostID for any item, I check to see if the cost item is relevant, if not I return an error message informing the user.I don't know, sometimes I think this application goes about 4000 steps too far!Mike B |
|
|
MikeB
Constraint Violating Yak Guru
387 Posts |
Posted - 2005-02-23 : 14:23:03
|
quote: Originally posted by MikeB
quote: Originally posted by rockmoose This seems like a very odd requirement.You must use dynamic sql to solve this, here is one solution:create table #tbEquipmentRental(fkItemID int, fkCostID int, Rate int, Units char(4))insert #tbEquipmentRentalselect 1,21,45,'DAY' unionselect 1,23,400,'LSUM' unionselect 2,22,225,'DAY'declare @fkItemID intset @fkItemID = 1 --<---------------------------- put value of fkItemID heredeclare @sql varchar(8000)set @sql = 'select t.fkItemID' + char(10)select @sql = @sql + ' ,t'+ltrim(fkCostID)+'.fkCostID,t'+ltrim(fkCostID)+'.Rate,t'+ltrim(fkCostID)+'.Units' + char(10)from #tbEquipmentRental where fkItemID = @fkItemIDset @sql = @sql + 'from (select '+ltrim(@fkItemID)+' as fkItemID) t' + char(10)select @sql = @sql + ' ,#tbEquipmentRental t'+ltrim(fkCostID) + char(10)from #tbEquipmentRental where fkItemID = @fkItemIDset @sql = @sql + 'where 1 = 1' + char(10)select @sql = @sql + ' and t'+ltrim(fkCostID)+'.fkItemID = '+ltrim(@fkItemID)+' and t'+ltrim(fkCostID)+'.fkCostID = '+ltrim(fkCostID) + char(10)from #tbEquipmentRental where fkItemID = @fkItemID-- select @sqlexec(@sql)drop table #tbEquipmentRental rockmoose
:)lol, it may be an odd requirment, I am full of them.The reason this is done is because for some equipment, some cost items are relavent and some aren't. For example, the fkItem 1 is crane rental. The fkCostID 21 = RENTAL and the fkCostID = MOVEINwhere as the fkItem 2 is trailer rental, where fkCostID = RENTAL, there is no "Movein" costs associated with it.I decided not to do it with the cross tab anyway. What I did was in the stored procedure for the update of a fkCostID for any item, I check to see if the cost item is relevant, if not I return an error message informing the user.I don't know, sometimes I think this application goes about 4000 steps too far! (the result of a few end user requirments where the end users have imaginations beyond my comprehension!)Mike B
|
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2005-02-23 : 14:43:57
|
>> I decided not to do it with the cross tab anyway. What I did was in the stored procedure for the update of a fkCostID for any item, I check to see if the cost item is relevant, if not I return an error message informing the user.Ok, but what does update have to do with crosstab anyway ??? And yes, stored procedures is the way to go.RAISERROR('This feature is not implemented yet, plz wait for next release',16,1)rockmoose |
|
|
MikeB
Constraint Violating Yak Guru
387 Posts |
Posted - 2005-02-23 : 15:05:27
|
quote: Originally posted by rockmoose >> I decided not to do it with the cross tab anyway. What I did was in the stored procedure for the update of a fkCostID for any item, I check to see if the cost item is relevant, if not I return an error message informing the user.Ok, but what does update have to do with crosstab anyway ??? And yes, stored procedures is the way to go.RAISERROR('This feature is not implemented yet, plz wait for next release',16,1)rockmoose
Well, that is a little harder to explain and I won't go into it here because it mostly revolves around c++ application which is off topic!Mike B |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2005-02-23 : 15:11:47
|
quote: Originally posted by robvolk This can't be done in SQL....
Can't be done?USE NorthwindGOSET NOCOUNT ONCREATE TABLE mytbEquipmentRental(fkItemID int, fkCostID int, Rate money, Units varchar(10))GOINSERT INTO mytbEquipmentRental(fkItemID, fkCostID, Rate, Units)SELECT 1, 21, 45, 'DAY' UNION ALLSELECT 1, 23, 400, 'LSUM' UNION ALLSELECT 2, 22, 225, 'DAY'GOCREATE FUNCTION GetAllOnLine(@id int)RETURNS VARCHAR(8000)ASBEGINDECLARE @Result VARCHAR(8000)SELECT @Result = COALESCE(@Result + '|','') + CONVERT(varchar(15),fkCostID)+ '|' +CONVERT(varchar(15),Rate) + '|' + UnitsFROM mytbEquipmentRentalWHERE fkItemID=@idRETURN @ResultENDGOCREATE VIEW myView99ASSELECT CONVERT(varchar(15),fkItemID) + '|' + dbo.GetAllOnLine(fkItemID) AS Data FROM (SELECT DISTINCT fkItemID FROM mytbEquipmentRental) AS XXXGOCREATE VIEW myExport99AS SELECT Data+REPLICATE('|',MAX_Delimiters - (LEN(Data)-LEN(REPLACE(DATA,'|','')))) AS ExportData FROM myView99CROSS JOIN ( SELECT MAX(LEN(Data)-LEN(REPLACE(DATA,'|',''))) AS MAX_Delimiters FROM myView99) AS XXXGOSELECT * FROM myExport99GODECLARE @cmd varchar(8000)SELECT @cmd = 'bcp Northwind.dbo.myExport99 out c:\myExport99.txt -c -Usa -P'EXECUTE master..xp_cmdshell @cmd GODECLARE @MAX_Columns int, @sql varchar(8000), @x int SELECT TOP 1 @Max_Columns = COUNT(*) FROM mytbEquipmentRentalGROUP BY fkItemIDORDER BY 1 DESCSELECT @sql = 'CREATE TABLE myTable99(fkItemID int', @x = 1WHILE @x < = @Max_Columns BEGIN SELECT @sql = @sql + ', fkCostID' + CONVERT(varchar(3),@x) + ' int' + ', Rate' + CONVERT(varchar(3),@x) + ' money' + ', Units' + CONVERT(varchar(3),@x) + ' varchar(10)' SELECT @x = @x + 1 ENDSELECT @sql = @sql + ')'SELECT @sqlEXEC(@sql)GOsp_help myTable99GODECLARE @cmd varchar(8000)SELECT @cmd = 'bcp Northwind.dbo.myTable99 in c:\myExport99.txt -c -t"|" -Usa -P'EXECUTE master..xp_cmdshell @cmd GOSELECT * FROM myTable99GODROP FUNCTION GetAllOnLineDROP VIEW myExport99DROP VIEW myView99DROP TABLE myTable99DROP TABLE mytbEquipmentRentalGO Brett8-) |
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2005-02-23 : 15:42:00
|
Brett,I have this table:tbBevwd | coffeetype | Amnt |--------------------------------1 | BH | 1 |2 | CR | 2 |3 | BL | 1 | Can I get sql server to do them for me each morning ?Or do I hace to GRANT SELECT ON tbev to wife ?rockmoose |
|
|
X002548
Not Just a Number
15586 Posts |
Posted - 2005-02-23 : 15:44:04
|
quote: Originally posted by rockmoose Brett,I have this table:tbBevwd | coffeetype | Amnt |--------------------------------1 | BH | 1 |2 | CR | 2 |3 | BL | 1 | Can I get sql server to do them for me each morning ?Or do I hace to GRANT SELECT ON tbev to wife ?rockmoose
I imagine you'd need the appropriate peripheralsBrett8-) |
|
|
|
|
|
|
|