Forum » Programiranje » T-SQL FIRST / TOP / MAX...
T-SQL FIRST / TOP / MAX...
nurmaln ::
Imam sledeč problemčič:
Artikel | Line No. | Text
000001 | 1 | Opis 1
000001 | 2 | Opis 2
000001 | 4 | Opis 3
000001 | 7 | Opis 4
000002 | 1 | Opis 1
000002 | 4 | Opis 2
000002 | 8 | Opis 3
000002 | 22 | Opis 4
Za izpis opisov posameznega artikla dam pač SELECT... WHERE Artikel = 000001 ORDER BY Line No
Potreboval bi pa izpis:
Artikel | Opis 1 | Opis 2 | Opis 3 |...
kakšna ideja?
Pudaril bi rad samo dejstvo, da Line No_ si sicer sledijo od njmanjšega do največjega ampak vmes je lahko večja razlika kot samo 1 (prikazano tudi zgoraj)
Artikel | Line No. | Text
000001 | 1 | Opis 1
000001 | 2 | Opis 2
000001 | 4 | Opis 3
000001 | 7 | Opis 4
000002 | 1 | Opis 1
000002 | 4 | Opis 2
000002 | 8 | Opis 3
000002 | 22 | Opis 4
Za izpis opisov posameznega artikla dam pač SELECT... WHERE Artikel = 000001 ORDER BY Line No
Potreboval bi pa izpis:
Artikel | Opis 1 | Opis 2 | Opis 3 |...
kakšna ideja?
Pudaril bi rad samo dejstvo, da Line No_ si sicer sledijo od njmanjšega do največjega ampak vmes je lahko večja razlika kot samo 1 (prikazano tudi zgoraj)
zigi ::
Ti bi rad dobil ven toliko stolpcev kot je različnih opisov, ali bi rad dal vse opise za določen artikel v en stolpec skupaj?
nurmaln ::
Pravzaprav bi mi koristili obe varjanti. Ampak če jih spravim v ločene stolpce, jih potem ni poseben problem še združiti v enega.
Microsoft ::
Hm, ce bo pomagalo:
SELECT DISTINCT [Text] FROM dbo.Table WHERE [Artikel] = '00000001'
Sicer je pa obracanje s PIVOT funkcijo malo tezje, ker aggregate functions ne delajo najbolje na stringu...
by Miha
SELECT DISTINCT [Text] FROM dbo.Table WHERE [Artikel] = '00000001'
Sicer je pa obracanje s PIVOT funkcijo malo tezje, ker aggregate functions ne delajo najbolje na stringu...
by Miha
s8eqaWrumatu*h-+r5wre3$ev_pheNeyut#VUbraS@e2$u5ESwE67&uhukuCh3pr
kopernik ::
Opisano težavo bi jaz rešil kar v aplikaciji in ne s poizvedbo na bazo (najbrž bi moral napisati kar stored proceduro, ker ne vem če je rešitev možna s standardnim sql). Se pravi, da bi naredil iteracijo čez rezultate in "ročno" zložil vse tekste v enega.
zigi ::
Dosti ljudi pravi 'cursors are bad for you', tu pa imaš primer vgnezdenega kurzorja
Recimo da imaš tabelo _tabela(artikel, naziv). Rezultat pa dobiš v tabeli ##temp.
Recimo da imaš tabelo _tabela(artikel, naziv). Rezultat pa dobiš v tabeli ##temp.
if exists (select 1 from tempdb..sysobjects where name = '##temp') drop table ##temp go create table ##temp (artikel varchar(16)) go --tukaj dobiš največje število opisov, da lahko dodaš ustrezno število stolpcev svoji novi tabeli declare @stOpisov int select @stOpisov = max(stOpisov) from ( select distinct artikel, count(1) stOpisov from _tabela group by artikel ) k declare @i int, @imeStolpca sysname, @ukaz varchar(1024) set @i = 1 while @i <= @stOpisov begin set @imeStolpca = 'Opis' + convert(varchar, @i) set @ukaz = 'alter table ##temp add ' + @imeStolpca + ' varchar(255)' exec(@ukaz) set @i = @i + 1 end insert into ##temp (artikel) select distinct artikel from _tabela order by artikel --ko imaš narejeno novo tabelo, vneseš podatke declare @artikel varchar(16), @naziv varchar(40), @artikelStari varchar(16) set @i = 0 set @artikelStari = (select top 1 artikel from _tabela order by artikel) declare c cursor local fast_forward for select distinct artikel from _tabela order by artikel open c fetch next from c into @artikel while @@fetch_status = 0 begin declare d cursor local fast_forward for select naziv from _tabela where artikel = @artikel order by naziv open d fetch next from d into @naziv while @@fetch_status = 0 begin if @artikel <> @artikelStari set @i = 1 else set @i = @i + 1 set @imeStolpca = 'Opis' + convert(varchar, @i) set @ukaz = 'update ##temp set ' + @imeStolpca + ' = ''' + @naziv + ''' where artikel = ''' + @artikel + '''' exec(@ukaz) set @artikelStari = @artikel fetch next from d into @naziv end close d deallocate d fetch next from c into @artikel end close c deallocate c
Zgodovina sprememb…
- spremenil: zigi ()
frudi ::
Ali je število opisov enako pri vseh artiklih? V tem primeru bi lahko uporabil dosti enostavnejšo rešitev. Ampak predvidevam, da ni, sicer bi imel tabelo s stolpci Text1, Text2, Text3.
Se pa sicer strinjam s kopernikom - takšne probleme, če je le možno, raje rešuj v aplikaciji, ne na bazi.
Če pa že hočeš po vsej sili to počet na bazi, pa je tule še ena rešitev brez kurzorjev. Sicer vsebuje eno WHILE zanko, ampak ta vsaj vsebuje le toliko korakov, kolikor je max. število opisov za posamezni artikel. Ta rešitev je tudi brez dinamičnih SQL stavkov in globalnih začasnih tabel, tako da se procedura ne bi smela vedno znova prevajat ob klicu. Dobiš pa na koncu že sestavljen opis za posamezni artikel. Če bi želel vsak opis v svojem stolpcu, je potrebna še kr precejšnja sprememba. Povej, če to nujno potrebuješ, pa se mogoče spravim dodat še to...
Se pa sicer strinjam s kopernikom - takšne probleme, če je le možno, raje rešuj v aplikaciji, ne na bazi.
Če pa že hočeš po vsej sili to počet na bazi, pa je tule še ena rešitev brez kurzorjev. Sicer vsebuje eno WHILE zanko, ampak ta vsaj vsebuje le toliko korakov, kolikor je max. število opisov za posamezni artikel. Ta rešitev je tudi brez dinamičnih SQL stavkov in globalnih začasnih tabel, tako da se procedura ne bi smela vedno znova prevajat ob klicu. Dobiš pa na koncu že sestavljen opis za posamezni artikel. Če bi želel vsak opis v svojem stolpcu, je potrebna še kr precejšnja sprememba. Povej, če to nujno potrebuješ, pa se mogoče spravim dodat še to...
-- začasna tabela za rezultat IF EXISTS(SELECT * FROM tempdb.INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '#ArtTemp%') DROP TABLE #ArtTemp CREATE TABLE #ArtTemp( Artikel NVARCHAR(8) NOT NULL, [Line No.] INT NOT NULL, [Text] NVARCHAR(100) NULL) -- v začasno tabelo shranimo Artikle in njihov najmanjši Line No. INSERT INTO #ArtTemp (Artikel, [Line No.]) SELECT Artikel, MIN([Line No.]) FROM _tabela GROUP BY Artikel -- v začasno tabelo dodamo še 1. opis UPDATE #ArtTemp SET #ArtTemp.[Text] = A.[Text] FROM _tabela AS A WHERE #ArtTemp.Artikel = A.Artikel AND #ArtTemp.[Line No.] = A.[Line No.] -- spremenljivki za iteracijo DECLARE @i INT DECLARE @colCount INT -- max število opisov za posamezni artikel SET @i = 1 SELECT @colCount = MAX(OPIS_COUNT) FROM (SELECT Artikel, COUNT([Text]) AS OPIS_COUNT FROM _tabela GROUP BY Artikel) AS X -- prištejmo še ostale opise... WHILE @i < @colCount BEGIN -- najprej označimo tiste artikle, ki eventualno več nimajo nobenega opisa (nastavimo jim Line No. na -1; lahko bi tudi drugače...) -- to preverimo tako, da preverimo, če obstaja še kak zapis z enakim Artikel in večjim Line No. UPDATE #ArtTemp SET #ArtTemp.[Line No.] = -1 WHERE NOT EXISTS( SELECT NULL FROM _tabela AS A WHERE #ArtTemp.Artikel = A.Artikel AND #ArtTemp.[Line No.] < A.[Line No.]) -- Line No. v začasni tabeli postavimo na naslednji najnižji Line No. izmed preostalih zapisov UPDATE #ArtTemp SET #ArtTemp.[Line No.] = X.MIN_LINE_NO FROM (SELECT Artikel, MIN([Line No.]) AS MIN_LINE_NO FROM _tabela AS A WHERE NOT EXISTS( -- tale pogoj izloči že dodane opise (* skupaj s pogojem za Line No. > -1) SELECT NULL FROM #ArtTemp AS T WHERE A.Artikel = T.Artikel AND A.[Line No.] <= T.[Line No.]) GROUP BY Artikel) AS X WHERE #ArtTemp.Artikel = X.Artikel AND #ArtTemp.[Line No.] > -1 -- * (glej opombo par vrstic višje...) -- v začasno tabelo 'prištejemo' še opise prej določenih naslednjih najnižjih Line No. UPDATE #ArtTemp SET #ArtTemp.[Text] = #ArtTemp.[Text] + ' ' + A.[Text] FROM _tabela AS A WHERE #ArtTemp.Artikel = A.Artikel AND #ArtTemp.[Line No.] = A.[Line No.] -- d0h... SET @i = @i + 1 END -- preverimo rezultat SELECT Artikel, [Text] FROM #ArtTemp
1ACDoHVj3wn7N4EMpGVU4YGLR9HTfkNhTd... in case I've written something useful :)
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [SQL] Pohitritev izpisaOddelek: Programiranje | 2901 (1800) | kuall |
» | PostgreSQL pomočOddelek: Programiranje | 2503 (1996) | Mato989 |
» | [SQL] Unikatni izpisiOddelek: Programiranje | 2218 (1605) | 111111111111 |
» | T-SQL preprost querry pa ne znamOddelek: Programiranje | 1820 (1477) | borchi |
» | [delphi] 2 bazi v eni mrežiOddelek: Programiranje | 1103 (1052) | seawolf |