MSSQL Lapozás a találati listában

MSSQL Lapozás a találati listában
2012-11-18T12:24:14+01:00
2012-11-20T09:21:04+01:00
2022-11-27T11:42:01+01:00
GZolee79
Sziasztok!

Nos a segítségetekkel sikerült összehozni nagyjából egy olyan tárolt eljárást amilyet szerettem volna.
De most elakadtam így további segítségre lenne szükségem.

Ez az eljárás működik, viszont azt nem sikerül megoldanom, hogy oldalakra tördeljem a találatokat.

Az eljárás:

CREATE PROCEDURE [dbo].[List_Meromuszerek_02] @muszer_tipus INT, @rendez VARCHAR(255)='' AS SELECT m.muszer_id, m.nyilv_szam, m.gyari_szam, m.megnevezes ,m.tipus, m.gyartmany, m.cikkszam, m.pontossagi_osztaly ,m.tartozekok, szk.szervezet, d.teljes_nev, m.uzembe_helyezes ,h.hasznalat_allapota, m.kalibralasi_utasitas_sz, m.megjegyzes FROM meromuszerek_tb m INNER JOIN szerv_kodok_tb szk ON m.szerv_kod = szk.szerv_kod INNER JOIN dolgozok_tb d ON m.szakmai_felelos_torzsszam=d.torzsszam INNER JOIN hasznalat_tb h ON m.hasznalat_allapot_id=h.id WHERE m.tipus_id=@muszer_tipus OR @muszer_tipus IS NULL ORDER BY CASE @rendez WHEN 'uzembe_helyezes' THEN (RANK() OVER (ORDER BY m.uzembe_helyezes)) WHEN 'nyilvszam' THEN (RANK() OVER (ORDER BY m.nyilv_szam)) WHEN 'gyari_szam' THEN (RANK() OVER (ORDER BY m.gyari_szam)) WHEN 'megnevezes' THEN (RANK() OVER (ORDER BY m.megnevezes)) WHEN 'tipus' THEN (RANK() OVER (ORDER BY m.tipus)) WHEN 'gyartmany' THEN (RANK() OVER (ORDER BY m.gyartmany)) WHEN 'cikkszam' THEN (RANK() OVER (ORDER BY m.cikkszam)) WHEN 'szerv_kod' THEN (RANK() OVER (ORDER BY m.szerv_kod)) WHEN 'leltari_felelos_torzzsam' THEN (RANK() OVER (ORDER BY m.leltari_felelos_torzsszam)) WHEN 'szakmai_felelos_torzzsam' THEN (RANK() OVER (ORDER BY m.szakmai_felelos_torzsszam)) WHEN '' THEN (RANK() OVER (ORDER BY m.muszer_id)) ELSE (RANK() OVER (ORDER BY m.muszer_id)) END

Gondolom valahogy A BETWEEN-EL kellene de nem tudom hová írjam, meg hogy számoljam meg a sorokat

A MYSQL-el könnyű volt a LIMIT-el de úgy tudom ez MSSQL-ben nincs.

Ha csak egyszerű SELECT van akkor megy a dolog de a fenti lekérdezésben nem sikerül.

Előre is köszi a segítséget!

Zoli
Mutasd a teljes hozzászólást!
SQL Server 2012-ben már lehet lapozni, OFFSET a kulcsszó, ha ilyened van.
Az előtte lévő veziókban többféleképpen is meg lehet oldani, itt egy lehetőség:

Csinálj egy CTE-t amibe beleteszed a query-d és row_number-el szűrsz rá.
Példa:


WITH cte AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY amit szerint akarod rendezni) rwn FROM táblák ... ) SELECT * FROM cte WHERE rwn BETWEEN @from AND @to
Mutasd a teljes hozzászólást!

  • Egy subselect-be Google mssql limit ötlete?

    Bár lehet, hogy egy "temp" tábla jobb lenne a belsőből.
    Mutasd a teljes hozzászólást!
  • SQL Server 2012-ben már lehet lapozni, OFFSET a kulcsszó, ha ilyened van.
    Az előtte lévő veziókban többféleképpen is meg lehet oldani, itt egy lehetőség:

    Csinálj egy CTE-t amibe beleteszed a query-d és row_number-el szűrsz rá.
    Példa:


    WITH cte AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY amit szerint akarod rendezni) rwn FROM táblák ... ) SELECT * FROM cte WHERE rwn BETWEEN @from AND @to
    Mutasd a teljes hozzászólást!
  • Igen, valami hasonlót próbáltam, de nem működik.
    Biztos rossz helyre írom vagy ilyesmi.
    Vagy a JOIN-ook kavarnak be valahogy.

    Így próbáltam de nem OK:

    CREATE PROCEDURE List_Meromuszerek_02 @muszer_tipus INT, @rendez VARCHAR(255)='' AS WITH CTE AS (SELECT m.muszer_id, m.nyilv_szam, m.gyari_szam, m.megnevezes ,m.tipus, m.gyartmany, m.cikkszam, m.pontossagi_osztaly ,m.tartozekok, szk.szervezet, d.teljes_nev, m.uzembe_helyezes ,h.hasznalat_allapota, m.kalibralasi_utasitas_sz, m.megjegyzes, ROW_NUMBER() OVER (ORDER BY CASE @rendez WHEN 'uzembe_helyezes' THEN (RANK() OVER (ORDER BY m.uzembe_helyezes)) WHEN 'nyilvszam' THEN (RANK() OVER (ORDER BY m.nyilv_szam)) WHEN 'gyari_szam' THEN (RANK() OVER (ORDER BY m.gyari_szam)) WHEN 'megnevezes' THEN (RANK() OVER (ORDER BY m.megnevezes)) WHEN 'tipus' THEN (RANK() OVER (ORDER BY m.tipus)) WHEN 'gyartmany' THEN (RANK() OVER (ORDER BY m.gyartmany)) WHEN 'cikkszam' THEN (RANK() OVER (ORDER BY m.cikkszam)) WHEN 'szerv_kod' THEN (RANK() OVER (ORDER BY m.szerv_kod)) WHEN 'leltari_felelos_torzzsam' THEN (RANK() OVER (ORDER BY m.leltari_felelos_torzsszam)) WHEN 'szakmai_felelos_torzzsam' THEN (RANK() OVER (ORDER BY m.szakmai_felelos_torzsszam)) WHEN '' THEN (RANK() OVER (ORDER BY m.muszer_id)) ELSE (RANK() OVER (ORDER BY m.muszer_id)) END) RWN FROM meromuszerek_tb m INNER JOIN szerv_kodok_tb szk ON m.szerv_kod = szk.szerv_kod INNER JOIN dolgozok_tb d ON m.szakmai_felelos_torzsszam=d.torzsszam INNER JOIN hasznalat_tb h ON m.hasznalat_allapot_id=h.id WHERE m.tipus_id=@muszer_tipus OR @muszer_tipus IS NULL) SELECT * FROM CTE WHERE RWN BETWEEN 100 AND 500

    Ezt a hibaüzenetet írja ki:
    Msg 4109, Level 15, State 1, Procedure List_Meromuszerek_02, Line 12
    Windowed functions cannot be used in the context of another windowed function or aggregate.
    Mutasd a teljes hozzászólást!
  • A Te verziódben ez így nézne ki, de ezzel a tárolt eljárással hosszú távon nem jársz jól:

    CREATE PROCEDURE List_Meromuszerek_02 @muszer_tipus INT, @rendez VARCHAR(255)='' AS WITH CTE AS ( SELECT m.muszer_id, m.nyilv_szam, m.gyari_szam, m.megnevezes ,m.tipus, m.gyartmany, m.cikkszam, m.pontossagi_osztaly ,m.tartozekok, szk.szervezet, d.teljes_nev, m.uzembe_helyezes ,h.hasznalat_allapota, m.kalibralasi_utasitas_sz, m.megjegyzes ,CASE @rendez WHEN 'uzembe_helyezes' THEN (RANK() OVER (ORDER BY m.uzembe_helyezes)) WHEN 'nyilvszam' THEN (RANK() OVER (ORDER BY m.nyilv_szam)) WHEN 'gyari_szam' THEN (RANK() OVER (ORDER BY m.gyari_szam)) WHEN 'megnevezes' THEN (RANK() OVER (ORDER BY m.megnevezes)) WHEN 'tipus' THEN (RANK() OVER (ORDER BY m.tipus)) WHEN 'gyartmany' THEN (RANK() OVER (ORDER BY m.gyartmany)) WHEN 'cikkszam' THEN (RANK() OVER (ORDER BY m.cikkszam)) WHEN 'szerv_kod' THEN (RANK() OVER (ORDER BY m.szerv_kod)) WHEN 'leltari_felelos_torzzsam' THEN (RANK() OVER (ORDER BY m.leltari_felelos_torzsszam)) WHEN 'szakmai_felelos_torzzsam' THEN (RANK() OVER (ORDER BY m.szakmai_felelos_torzsszam)) WHEN '' THEN (RANK() OVER (ORDER BY m.muszer_id)) ELSE (RANK() OVER (ORDER BY m.muszer_id)) END RWN FROM meromuszerek_tb m INNER JOIN szerv_kodok_tb szk ON m.szerv_kod = szk.szerv_kod INNER JOIN dolgozok_tb d ON m.szakmai_felelos_torzsszam=d.torzsszam INNER JOIN hasznalat_tb h ON m.hasznalat_allapot_id=h.id WHERE m.tipus_id=@muszer_tipus OR @muszer_tipus IS NULL ) SELECT * FROM CTE WHERE RWN BETWEEN 100 AND 500
    Mutasd a teljes hozzászólást!
  • Értem. És mit javasolsz? Hogyan kellene megoldani a problémát?

    Átírtam, úgy ahogy Riha javasolta az előző kérdésben amit feltettem.
    Valóban sokkal egyszerűbb így. De nem baj ha megismerek több technikát.

    Így néz ki most a kódom:


    CREATE PROCEDURE [dbo].[List_Meromuszerek_02] @muszer_tipus INT, @rendez VARCHAR(255)='', @FROM INT, @TO INT AS DECLARE @sql VARCHAR(2000), @Row_Count INT SET @Row_Count = (SELECT COUNT(muszer_id) FROM meromuszerek_tb WHERE tipus_id=@muszer_tipus OR @muszer_tipus IS NULL); SET @sql ='WITH CTE AS (SELECT m.muszer_id, m.nyilv_szam, m.gyari_szam, m.megnevezes ,m.tipus, m.gyartmany, m.cikkszam, m.pontossagi_osztaly ,m.tartozekok, szk.szervezet, d.teljes_nev, m.uzembe_helyezes ,h.hasznalat_allapota, m.kalibralasi_utasitas_sz, m.megjegyzes, ROW_NUMBER() OVER(ORDER BY @rendez) RWN FROM meromuszerek_tb m INNER JOIN szerv_kodok_tb szk ON m.szerv_kod = szk.szerv_kod INNER JOIN dolgozok_tb d ON m.szakmai_felelos_torzsszam=d.torzsszam INNER JOIN hasznalat_tb h ON m.hasznalat_allapot_id=h.id WHERE m.tipus_id=@muszer_tipus OR @muszer_tipus IS NULL) SELECT * FROM CTE WHERE RWN BETWEEN @FROM AND @TO' SET @sql = replace (@Sql,'@rendez',@rendez) SET @sql = replace (@sql,'@muszer_tipus', @muszer_tipus) SET @sql = replace (@sql,'@FROM', @FROM) SET @sql = replace (@sql,'@TO', @TO) EXEC (@Sql) RETURN @Row_Count;

    Ez már majdnem teljesen jó, de csak van még egy probléma vele amit nem értek.
    Itt van ez a feltétel:

    WHERE tipus_id=@muszer_tipus OR @muszer_tipus IS NULL);


    Ha a @muszer_tipus=NULL akkor nem hoz egyetlen sort sem, de csak ott ahol beállítom az @sql értékét.

    Ahol csak megszámolom a sorokat ott rendesen működik.
    Mi lehet a hiba?
    Mutasd a teljes hozzászólást!
  • Ha a @muszer_tipus=NULL akkor nem hoz egyetlen sort sem

    Ez jogos, biztos, hogy a paraméterre akarod a vizsgálatot, vagy inkább az oszlopra?

    WHERE isnull(m.tipus_id,0)=@muszer_tipus
    Mutasd a teljes hozzászólást!
  • Hát úgy szeretném csinálni, hogy van 3 féle műszer típus.
    Ha 1-es akkor az 1-eseket listázza, ha 2-es akkor a 2-eseket és ugyanígy a 3-asokra is.

    Ha viszont nem adok át értéket, vagyis null értéket adok át akkor listázza ki az összeset.
    Erre tudsz másik módszert?

    Ha csak simán beírom egy query-be és nem tárolt eljárásba akkor működik is.

    Viszont itt hajlandó.

    Közben rájöttem, hogy az a baj, hogy ebben a sorban

    SET @sql = replace (@sql,'@muszer_tipus', @muszer_tipus)
    kicseréli az összeset és ebből:

    WHERE m.tipus_id=@muszer_tipus OR @muszer_tipus IS NULL)

    ez lesz (ha mondjuk 1-et adok át):

    WHERE m.tipus_id=1 OR 1 IS NULL)

    Ugye bár ez nem jó.

    Ezért azt gondoltam bevezetek még egy változót, hogy ne cserélje ki.

    Így modosítottam:

    WHERE m.tipus_id=@muszer_tipus OR @musz_tipus IS NULL)

    Persze a előtte deklaráltam
    így:

    DECLARE @musz_tipus INT --adni akartam neki értéket SET @musz_tipus = @muszer_tipus;

    De mégis ezt a hibát dobja mikor futtatom (lefordulni lefordul):
    Must declare the scalar variable "@musz_tipus".
    Mutasd a teljes hozzászólást!
  • Ha viszont nem adok át értéket, vagyis null értéket adok át akkor listázza ki az összeset.
    Erre tudsz másik módszert?

    Igen.
    Ez esetben ne legyen WHERE.

    CREATE PROCEDURE List_Meromuszerek_02 @muszer_tipus INT, @rendez VARCHAR(255)='' AS IF IsNull(@muszer_tipus,0) = 0 Begin -- és itt nincs e paraméterre vizsgálat WITH CTE AS ( SELECT END ELSE Begin -- itt van WITH CTE AS ( SELECT End
    szerk.
    Mutasd a teljes hozzászólást!
  • Na, végül így sikerült megoldanom.
    Azt hiszem több megoldás is benne van amit adtatok.
    Köszi:


    ALTER PROCEDURE [dbo].[List_Meromuszerek] @muszer_tipus INT = NULL, @rendez VARCHAR(255)='m.muszer_id', @FROM INT, @TO INT AS DECLARE @sql VARCHAR(2000), @Row_Count INT SET @Row_Count = (SELECT COUNT(muszer_id) FROM meromuszerek_tb WHERE tipus_id=@muszer_tipus OR @muszer_tipus IS NULL); IF IsNull(@muszer_tipus,0) = 0 BEGIN SET @sql ='WITH CTE AS (SELECT m.muszer_id, m.nyilv_szam, m.gyari_szam ,m.megnevezes,m.tipus, m.gyartmany, m.cikkszam ,m.pontossagi_osztaly ,m.tartozekok, szk.szervezet ,d.teljes_nev, m.uzembe_helyezes ,h.hasznalat_allapota, m.kalibralasi_utasitas_sz ,m.megjegyzes,ROW_NUMBER() OVER(ORDER BY @rendez) RWN FROM meromuszerek_tb m INNER JOIN szerv_kodok_tb szk ON m.szerv_kod = szk.szerv_kod INNER JOIN dolgozok_tb d ON m.szakmai_felelos_torzsszam=d.torzsszam INNER JOIN hasznalat_tb h ON m.hasznalat_allapot_id=h.id ) SELECT * FROM CTE WHERE RWN BETWEEN @FROM AND @TO' END ELSE BEGIN SET @sql ='WITH CTE AS (SELECT m.muszer_id, m.nyilv_szam, m.gyari_szam ,m.megnevezes, m.tipus, m.gyartmany, m.cikkszam, m.pontossagi_osztaly ,m.tartozekok, szk.szervezet ,d.teljes_nev, m.uzembe_helyezes,h.hasznalat_allapota ,m.kalibralasi_utasitas_sz, m.megjegyzes, ROW_NUMBER() OVER(ORDER BY @rendez) RWN FROM meromuszerek_tb m INNER JOIN szerv_kodok_tb szk ON m.szerv_kod = szk.szerv_kod INNER JOIN dolgozok_tb d ON m.szakmai_felelos_torzsszam=d.torzsszam INNER JOIN hasznalat_tb h ON m.hasznalat_allapot_id=h.id WHERE m.tipus_id=@muszer_tipus) SELECT * FROM CTE WHERE RWN BETWEEN @FROM AND @TO' SET @sql = replace (@sql,'@muszer_tipus', @muszer_tipus) END SET @sql = replace (@Sql,'@rendez',@rendez) SET @sql = replace (@sql,'@FROM', @FROM) SET @sql = replace (@sql,'@TO', @TO) EXEC (@Sql) RETURN @Row_Count;

    Ez a kód lekérdezi az általam kiválasztatott sorokat.
    Bemenő paraméter alapján rendez és ugyanígy választja ki a műszertípust.
    Valamint a lapozást is a bemenő paraméterek alapján végzi el.

    Mivel több megoldást is felhasználtam egyenlőre nem tudom kinek adjam a pontot.
    A megoldás alapján szerintetek kit illet ?

    Egyenlőre mindenkinek köszi!
    Mutasd a teljes hozzászólást!
  • A megoldás alapján szerintetek kit illet ?

    Aki az alapot adta:
    Csinálj egy CTE-t amibe beleteszed a query-d és row_number-el szűrsz rá.

    A többi már csak az apróbb botladozásod egyengette.
    Sok sikert.
    Mutasd a teljes hozzászólást!
  • Hát akkor köszi!

    Sok kérdésem lesz még biztos, úgyhogy majd jelentkezem!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd