Hej. Själv så skulle jag lösa själva vridningen av resultatet i kod för då kan du slå ihop allt i en enda join, men måste du lösa det i sql så ska du antingen kolla på cursors (slött om det är mycket data som hämtas) eller mssql's olap funktioner för att sammanställa statistik (också rätt så slött vid stora datamängder). Kanske något sådant här fungerar? Hej. Varför fungerar inte mitt sätt att lösa det på? Det är väl enklare? Varför har du välten som varchar istället för tal? Hej Andreas. Hej igen. Är det inte bara att göra en SELECT ... INTO? Hej igen... Hej igen. JAG tycker att du kan optimera:Dynamisk resultat...
Sitter med ett problem i SQL-Server 2000 som jag inte kan lösa... (frågan går inte tillräckligt snabbt iallafall)
Problemet förenklat:
tblBilar:
id int, märkesid int, däcktypsid int
ex:
1 1 1
2 3 4
3 4 5
4 5 3
osv...
tblBilmärken:
id int, Märke varchar
ex:
1 volvo
2 Saab
3 Opel
4 Ford
osv...
tblDäckTyp
id int, Typ varchar
ex:
1 Traktor
2 Lågprofil
3 Vinter
4 Odubbade
osv...
Hur gör jag för att få ut en tabell liknade denna: (Exempel, stämmer inte med ovan)
Läs den såhär:
"76 Saabar har Lågprofilsdäck"
"3 volvo har Traktordäck"
[Bilmärke] [Antal Traktor] [Antal Lågprofil] [Antal Vinter] [Antal Odubbade]
Saab 99 76 78 21
Volvo 3 3 34 34
Ford 0 24 19 89
Tabellen skall alltså med tiden kunna "växa" både på bredden och på längden...
Det vore himla bra om ni kunde hjälpa mig framåt på nåt vis...Sv: Dynamisk resultat...
Sv: Dynamisk resultat...
DECLARE @SQL varchar(1000)
DECLARE @Fields varchar(1000)
SET @Fields = 'tblBilmärken.Märke'
SELECT @Fields = @Fields + ', SUM(CASE tblBilar.DäckTypsId WHEN ' + CAST(tblDäckTyp.ID AS varchar) + ' THEN 1 ELSE 0 END) AS [Antal ' + tblDäckTyp.Typ + ']'
FROM tblDäckTyp
SET @Fields = 'SELECT ' + @Fields + ' FROM tblBilmärken LEFT JOIN tblBilar ON tblBilmärken.id = tblBilar.MärkesId GROUP BY tblBilmärken.Märke'
EXEC @SQL
Har för mig att man använder " tecken istället för AS [ och ]. Så du får ev. ändra det till " tecken om den klagar på det.Sv: Dynamisk resultat...
Tackar för att ni tagit er tid...
Min lösning bygger på dynamisk SQL.
Nedan använder jag de rätta tabellnamnen och definitionerna:
tblCase = tblBilar
tblBilmärken = tblSubCat
tblDäckTyp = tblCaseType
Den är seg men den fungerar så här långt. (Mer skall göras...)
<code>
declare @pDateStart varchar(10)
declare @pDateStop varchar(10)
set @pDateStart = '2002-01-01'
set @pDateStop = '2003-02-01'
declare @sql varchar(8000)
declare @sqls varchar(8000)
declare @ct table(ctID int, [ctName] varchar(30))
declare @minid int
declare @ctName varchar(30)
insert into @ct
select ctID, ctName from tblCaseType
where ctID <> 1
set @sql = 'declare @case table(sCatId int, ctID int);' + char(10)
set @sql = @sql + 'insert into @case ' + char(10)
set @sql = @sql + 'select sCatID, caseTypeID from tblCase where caseTypeID <> 1 and CONVERT(VARCHAR(10), regDate, 121) between ''' + @pDateStart + ''' and ''' + @pDateStop + ''' and statusID = 7;' + char(10)
set @sql = @sql + ' declare @s table(mCatId int, sCatID int'
set @sqls = 'select tblSubCat.mCatID, tblSubCat.sCatID' + char(10)
set @minid = (select min(ctID) from @ct)
while not @minid is null
begin
set @ctName = (select ctName from @ct
where ctID = @minid)
set @sql = @sql + ', [' + @ctName + '] varchar(30)'
set @sqls = @sqls + ltrim(' , (select count(*) from @case where scatid = tblSubCat.sCatID and ctID = ' + ltrim(str(@minid)) + ')') + char(10)
set @minid = (select min(ctID) from @ct
where ctID > @minid)
end
set @sql = @sql + ');' + char(10)
set @sqls = @sqls + ' from tblSubCat' + char(10)
set @sql = @sql + ' insert into @s ' + char(10)
select @sql + @sqls + '; select * from @s'
</code>
Denna kod ger en textsträng:
<code>
declare @case table(sCatId int, ctID int);
insert into @case
select sCatID, caseTypeID from tblCase where caseTypeID <> 1 and CONVERT(VARCHAR(10), regDate, 121) between '2002-01-01' and '2003-02-01' and statusID = 7;
declare @s table(mCatId int, sCatID int, [Version 1] varchar(30), [Teknik] varchar(30), [Ekonomi] varchar(30), [Biologi] varchar(30), [Fysik] varchar(30), [gg] varchar(30));
insert into @s
select
tblSubCat.mCatID
, tblSubCat.sCatID
, (select count(*) from @case where scatid = tblSubCat.sCatID and ctID = 2)
, (select count(*) from @case where scatid = tblSubCat.sCatID and ctID = 7)
, (select count(*) from @case where scatid = tblSubCat.sCatID and ctID = 8)
, (select count(*) from @case where scatid = tblSubCat.sCatID and ctID = 9)
, (select count(*) from @case where scatid = tblSubCat.sCatID and ctID = 10)
, (select count(*) from @case where scatid = tblSubCat.sCatID and ctID = 11)
from tblSubCat
; select * from @s
</code>
Kör jag denna textsträng "exec(@sql + @sqls + '; select * from @s')"
får jag ut ett resultat jag är nöjd med...
* Finns det andra sätt att göra detta på (i TSQL)? Optimering, andra sql-satser...?
* Kan jag få ut resultatet av en liknade sträng
ex:
<code>
exec('select * from tblCase')
</code>
till en temptabell eller en tempvariabel?
Hur göra??Sv: Dynamisk resultat...
Sv: Dynamisk resultat...
Jag försökte få till det i morse men lyckades inte med din kod.
När du skrev tillbaka nu så försökte jag igen...
Det fungerade !!! Smart var det också...
Resultatet: (Efter lite omskrivning)
declare @pDateStart varchar(10)
declare @pDateStop varchar(10)
set @pDateStart = '2002-01-01'
set @pDateStop = '2003-09-01'
DECLARE @SQL varchar(8000)
DECLARE @Fields varchar(8000)
SET @Fields = 'tblSubCat.sCatName'
SELECT @Fields = @Fields + ', SUM(CASE tblCase.caseTypeID WHEN ' + CAST(tblCaseType.ctID AS varchar) + ' THEN 1 ELSE 0 END) AS [Antal ' + tblCaseType.ctName + ']'
FROM tblCaseType
SET @SQL = 'SELECT ' + @Fields + ' FROM tblSubCat
LEFT JOIN tblCase
ON tblSubCat.sCatID = tblCase.sCatID
where
(CONVERT(VARCHAR(10), tblCase.regDate, 121) between ''' + @pDateStart + ''' and ''' + @pDateStop + ''')
and (tblCase.statusID = 7)
GROUP BY tblSubCat.sCatName'
exec(@SQL)
Testar vidare på detta....
Fler idéer??Sv: Dynamisk resultat...
Klockren. Fy fasen vad bra!
Hur kan jag nu få ut resultatet i en tabellvariabel eller temptabell???
Typ:
declare @tmp table(id int.... .... ... ... ... ... )
exec(@SQL)
select * from @tmpSv: Dynamisk resultat...
declare @pDateStart varchar(10)
declare @pDateStop varchar(10)
set @pDateStart = '2002-01-01'
set @pDateStop = '2003-09-01'
DECLARE @SQL varchar(8000)
DECLARE @Fields varchar(8000)
SET @Fields = 'tblSubCat.sCatName'
SELECT @Fields = @Fields + ', SUM(CASE tblCase.caseTypeID WHEN ' + CAST(tblCaseType.ctID AS varchar) + ' THEN 1 ELSE 0 END) AS [Antal ' + tblCaseType.ctName + ']'
FROM tblCaseType
SET @SQL = 'SELECT ' + @Fields + ' INTO #TempTable FROM tblSubCat
LEFT JOIN tblCase
ON tblSubCat.sCatID = tblCase.sCatID
where
(CONVERT(VARCHAR(10), tblCase.regDate, 121) between ''' + @pDateStart + ''' and ''' + @pDateStop + ''')
and (tblCase.statusID = 7)
GROUP BY tblSubCat.sCatName'
SELECT *
FROM #TempTable
DROP TABLE #TempTable
Eventuellt får du placera det två sista satserna i SQL strängen istället.Sv: Dynamisk resultat...
Var tvungen att lägga in detta i strängen...
Det var det jag ville slippa...
Antar att jag får fortsätta vara i "embedded"-läge till jag har mitt färdiga resultat.
Det vill jag ju helst slippa...
Men sakta men säkert går det framåt...
Återkommer....
TACK!Sv: Dynamisk resultat...
Glömde att redovisa resultatet av den färdiga frågan:
**********************************************************************
CREATE PROCEDURE dbo.sp_AHV2_HIS_R03
@pDateStart varchar(10),
@pDateStop varchar(10)
AS
set nocount on
DECLARE @SQL varchar(8000)
DECLARE @Fields varchar(8000)
SET @Fields = 'tblMainCat.mCatName as [Huvudkategori], isnull(tblSubCat.sCatName, '''') as [Underkategori]'
SELECT @Fields = @Fields + ', SUM(CASE tblCase2.caseTypeID WHEN ' + CAST(tblCaseType.ctID AS varchar) + ' THEN 1 ELSE 0 END) AS [' + tblCaseType.ctName + ']'
FROM tblCaseType
where tblCaseType.ctID <> 1
SET @SQL = 'SELECT ' + @Fields + ' FROM tblMainCat
full outer join tblSubCat
on tblMainCat.mCatID = tblSubCat.mCatID
full outer join (select caseTypeID, sCatID from tblCase where ((CONVERT(VARCHAR(10), tblCase.regDate, 121) between ''' + @pDateStart + ''' and ''' + @pDateStop + ''') and (tblCase.statusID = 7))) as tblCase2
on tblSubCat.sCatID = tblCase2.sCatID
GROUP BY tblMainCat.mCatName, tblSubCat.sCatName
order by tblMainCat.mCatName, tblSubCat.sCatName collate Finnish_Swedish_CI_AI'
exec(@SQL)
GO
**********************************************************************
Tack igen Andreas.Sv: Dynamisk resultat...
((CONVERT(VARCHAR(10), tblCase.regDate, 121) between ''' + @pDateStart + ''' and ''' + @pDateStop + ''')
Till:
(tblCase.regDate BETWEEN CAST(''' + @pDateStart + ''' AS datetime) AND CAST(''' + @pDateStop + ''' AS datetime))
Då konverterar du bara två konstanter istället för alla datumfält i databasen. Tror även sökmotorn kan tillgodose sig index då.