Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[MSSQL] wil regel 3 tot 6 uit bepaalde tabel *

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

ik heb 1 grootte tabel waar ik diverse projecten in heb zitten. Deze projecten hangen weer gekoppeld aan een SubID.

Tabel
code:
1
2
3
4
5
6
7
8
9
10
ProID   SubID      Omschrijving
1              8              Plaatje 1
2              9              Plaatje 1
3              8              Plaatje 2
4              8              testmh3
9              9              test9
14            8               test 4
18            8               test567
19            9               test1
20            8               blabla


Ik heb al een stored procedure zodat ik weet hoeveel projecten ik met SubID: "8" heb:
code:
1
2
3
4
5
6
7
8
9
@pId int,
@Count int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET @COUNT = (SELECT COUNT (ProID)
FROM projecten
where (SubID=@pId))
END


Deze werkt goed. De eerste drie van SubID 8 kan ik ook nog tevoorschijn toveren met top (3)

Maar ik wil nu nummer 4 tot 6 laten zien.

Weet iemand zoiets, ik werk met Visual Studio 2005 en met SQL Server Management Studio 2005

  • lier
  • Registratie: Januari 2004
  • Laatst online: 22:36

lier

MikroTik nerd

Wil je dit in je Stored Procedure verwerken, of wil je deze keuze in code doen ?

Eerst het probleem, dan de oplossing


Verwijderd

Topicstarter
Als het kan in een Stored Procedure

  • DamadmOO
  • Registratie: Maart 2005
  • Laatst online: 19:04
Door gebruik te maken van een subquery kan het.
code:
1
2
3
4
SELECT *
FROM projecten
WHERE SubID=@pId
AND ProID NOT IN (SELECT TOP 3 * FROM projecten WHERE SubID = @pId )

Note: code verder niet getest.

Verwijderd

Topicstarter
DamadmOO schreef op woensdag 13 februari 2008 @ 14:28:
Door gebruik te maken van een subquery kan het.
code:
1
2
3
4
SELECT *
FROM projecten
WHERE SubID=@pId
AND ProID NOT IN (SELECT TOP 3 * FROM projecten WHERE SubID = @pId )

Note: code verder niet getest.
Maar dit werkt niet van 3 tot 6, misschien is er straks ook een nummer 7

Ik zat al te denken om alles van hetrzelfde SubID te kopieren naar een nieuwe tabel met een vaast nummer 1 t/m max 27 en daar dan het ID 4, 5 en 6 uit te halen, laten kan ik hier dan ook 7,8 en 9 uit halen. Maar dit genereerd, denk ik, veel dataverkeer.

[ Voor 23% gewijzigd door Verwijderd op 13-02-2008 14:30 ]


  • DamadmOO
  • Registratie: Maart 2005
  • Laatst online: 19:04
Verwijderd schreef op woensdag 13 februari 2008 @ 14:29:
[...]
Maar dit werkt niet van 3 tot 6, misschien is er straks ook een nummer 7
Beetje nadenken zou je niet misstaan.

Dan gebruik je toch gewoon een TOP in de hoofd query?

  • KabouterSuper
  • Registratie: September 2005
  • Niet online
Top 6 minus top 3

When life gives you lemons, start a battery factory


  • lier
  • Registratie: Januari 2004
  • Laatst online: 22:36

lier

MikroTik nerd

Kan je eens uitleggen waarom je exact deze waarden wil hebben ?
Waarom wil je dit op DB niveau oplossen en bijvoorbeeld niet in code ?

Overigens is je vraag wel heel erg basic ;) -TSQL, even zoeken op Inet zou zeker het antwoord op deze specifieke vraag moeten geven.

Eerst het probleem, dan de oplossing


  • Shezzie
  • Registratie: Januari 2005
  • Laatst online: 06-10 20:24

Shezzie

Lekker hoor!

Ik zou idd gewoon de hele set naar me toe trekken en dit met wat logica in de software oplossen. Mocht je echter toch steeds 3 records willen hebben omdat je bijvoorbeeld anders geheugenproblemen krijgt, dan is het makkelijkste om de ProdID van je laatste record te bufferen en als ondergrens te gebruiken:

SELECT TOP 3 *
FROM Projecten
WHERE ProdID > [laatste ID van de vorige set records]
AND SubID=@pId

Verwijderd

Topicstarter
lier schreef op woensdag 13 februari 2008 @ 14:36:
Kan je eens uitleggen waarom je exact deze waarden wil hebben ?
Waarom wil je dit op DB niveau oplossen en bijvoorbeeld niet in code ?

Overigens is je vraag wel heel erg basic ;) -TSQL, even zoeken op Inet zou zeker het antwoord op deze specifieke vraag moeten geven.
Ik wil het het liefst in een stored procedure, daar werk ik nu eenmaal vaak mee.

Ik zal eens kijken ofdat ik het beter kan uitleggen

  • Shezzie
  • Registratie: Januari 2005
  • Laatst online: 06-10 20:24

Shezzie

Lekker hoor!

Leuke naam van je zoon btw 8)

Verwijderd

Je kan gebruik maken van de NOT IN optie, echter kan dit erg zwaar worden voor het systeem (weet ik uit ervaring).

SQL:
1
2
3
select top 10 <kolom> 
from <tabel> 
where id not in (select top 10 id from <tabel> order by id) order by id


Geef me de eerste 10 regels uit de tabel waarvoor geld dat het niet de eerste 10 zijn, met andere woorden, geef me records 11 t/m 20. Je moet zelf uitzoeken welke waarden beide 10's zijn, deze zijn niet gelijk. Dit kan in een SP waarbij het beide een parameter is.

Indien je tabel erg groot (in aantal records en aantal kolommen / joins) is dan kan de NOT IN erg belastend worden voor je systeem, dit omdat er geen handige index gebruikt kan worden.

Wil dat (toekomstige?) probleem meteen omzeilen zal je met sub queries en de functie rownumber() moeten gaan werken. Een duw in de richting, eerst alle records ophalen die aan je criteria voldoen, hier rownumber overheen halen en dan met between op rownumber een subselect eruit filteren.

Ik heb een voorbeeld eventueel beschikbaar.


edit:

Mijn voorbeeld gaat uit van een afwijkende sortering, dus geen sortering op de ID kolom. Indien de sortering altijd plaats vindt op ID dan is de oplossing zoals hierboven aangegeven met > ook een goede oplossing.

[ Voor 9% gewijzigd door Verwijderd op 13-02-2008 14:54 ]


  • lier
  • Registratie: Januari 2004
  • Laatst online: 22:36

lier

MikroTik nerd

Verwijderd schreef op woensdag 13 februari 2008 @ 14:52:
Je kan gebruik maken van de NOT IN optie, echter kan dit erg zwaar worden voor het systeem (weet ik uit ervaring).

SQL:
1
2
3
select top 10 <kolom> 
from <tabel> 
where id not in (select top 10 id from <tabel> order by id) order by id


Geef me de eerste 10 regels uit de tabel waarvoor geld dat het niet de eerste 10 zijn, met andere woorden, geef me records 11 t/m 20. Je moet zelf uitzoeken welke waarden beide 10's zijn, deze zijn niet gelijk. Dit kan in een SP waarbij het beide een parameter is.

Indien je tabel erg groot (in aantal records en aantal kolommen / joins) is dan kan de NOT IN erg belastend worden voor je systeem, dit omdat er geen handige index gebruikt kan worden.

Wil dat (toekomstige?) probleem meteen omzeilen zal je met sub queries en de functie rownumber() moeten gaan werken. Een duw in de richting, eerst alle records ophalen die aan je criteria voldoen, hier rownumber overheen halen en dan met between op rownumber een subselect eruit filteren.

Ik heb een voorbeeld eventueel beschikbaar.


edit:

Mijn voorbeeld gaat uit van een afwijkende sortering, dus geen sortering op de ID kolom. Indien de sortering altijd plaats vindt op ID dan is de oplossing zoals hierboven aangegeven met > ook een goede oplossing.
Ter aanvulling op dit (al bijna volledig uitgekauwde verhaal), als je het configurabel wil maken, zal je gebruik moeten maken van ROWCOUNT. Deze is namelijk dynamisch te zetten in de Stored Procedure, in tegenstelling tot de TOP functie.
Ik zal eens kijken ofdat ik het beter kan uitleggen
Beter...?

Eerst het probleem, dan de oplossing


  • roeleboel
  • Registratie: Maart 2006
  • Niet online

roeleboel

en zijn beestenboel

Volgens mij kan je hier gebruik maken van een 'cursor' binnen de stored procedure, waarmee je over je recordset heenloopt & er dan mooi record 3 tot 6 (of x tot y, al naargelang je de functie schrijft natuurlijk) uitpikt (met een simpel tellertje bijvoorbeeld).

Meer info over cursors: zie de handleiding van de sql-server die je gebruikt, want dit wil nogal eens verschillen van versie tot versie heb ik de indruk.
(disclaimer: zelf geen ervaring met die dingen, wel een vaag benul van wat je er mee zou moeten kunnen :))

De makkelijkste manier om hyprocrieten boos te krijgen? Confronteer ze met hun eigen uitspraken...


Verwijderd

Topicstarter
Dit werkt, hier kan ik in ieder geval op verder. Bedankt!
code:
1
2
3
4
5
6
7
8
9
10
11
@pId int
AS
BEGIN
SET NOCOUNT ON;
SELECT  TOP (6) SubID, ProID
FROM         Projecten
WHERE     
(SubID = @pId) 
and 
(ProID not in (select top 3 ProID from Projecten WHERE (SubID = @pId)))
END

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Verwijderd schreef op woensdag 13 februari 2008 @ 14:52:
Je kan gebruik maken van de NOT IN optie, echter kan dit erg zwaar worden voor het systeem (weet ik uit ervaring).
Hoezo zwaar? :?

Deze aanpak is dermate standaard dat de query optimizer het volledig wegoptimaliseert als je het execution plan opvraagt. Dit kan alleen slecht performen als je geen index op de te filteren column hebt gelegd (en dan zal het idd exponentieel slecht lopen).

Professionele website nodig?


Verwijderd

curry684 schreef op woensdag 13 februari 2008 @ 15:47:
[...]

Hoezo zwaar? :?

Deze aanpak is dermate standaard dat de query optimizer het volledig wegoptimaliseert als je het execution plan opvraagt. Dit kan alleen slecht performen als je geen index op de te filteren column hebt gelegd (en dan zal het idd exponentieel slecht lopen).
In ons geval konden we niet veel meer met indexen oplossen, dit omdat de where afhankelijk was van het zoekscherm binnen het systeem. Hierdoor waren er bijna oneindig veel zoekcombinaties mogelijk en tevens moest het invoegen van records net zo snel bijven. Uiteindelijk hebben we het opgelost door de query om te bouwen naar een drie dubbele subquery en met rownumber te werken, Dit bracht de executietijd terug naar tientallen tot enkele honderden milisecondes in plaats van enkele minuten.

Het voorbeeld van de topic starter is goed te doen met de not in combinatie. Zodra de tabel erg veel joins en ingewikkelde where statements gaat bevatten wordt het interesant om te gaan kijken naar alternatieve methoden.

Ik zou trouwens die 6 en 3 in je SP vervangen door parameters.
Pagina: 1