Microsoft SQL Server 2000 & # 39; de MySQL LİMİT yan tümcesini taklit edin

Zend Framework'ün veritabanı bileşeni üzerinde çalıştığımda , MySQL, PostgreSQL ve SQLite tarafından desteklenen LIMIT maddesinin işlevselliğini özetlemeye çalıştık. Yani, bir sorgu oluşturmak şu şekilde yapılabilir:

$select = $db->select();
$select->from('mytable');
$select->order('somecolumn');
$select->limit(10, 20);

veritabanı LIMIT Desteklediğinde, bu aşağıdaki gibi bir SQL sorgusu üretir:

SELECT * FROM mytable ORDER BY somecolumn LIMIT 10, 20

bu, veritabanı markaları için daha karmaşıktı destek LIMIT (bu madde standart SQL dilinin bir parçası değildir, bu arada). Satır numaralarını üretebilirseniz, tüm sorguyu türetilmiş bir tablo yapın ve dış sorguda BETWEEN kullanın . Bu, Oracle ve IBM DB2 için çözümdü. Microsoft SQL Server 2005 benzer bir satır numarası işlevi vardır, bu nedenle sorgu bu şekilde yazabilirsiniz:

SELECT z2.*
FROM (
    SELECT ROW_NUMBER OVER(ORDER BY id) AS zend_db_rownum, z1.*
    FROM ( ...original SQL query... ) z1
) z2
WHERE z2.zend_db_rownum BETWEEN @offset+1 AND @[email protected];

ancak, Microsoft SQL Server 2000 ROW_NUMBER() işlevi yok.

Yani sorum şu ki, yalnızca SQL kullanarak Microsoft SQL Server 2000'de LIMIT işlevselliğini taklit etmenin bir yolunu bulabilir misiniz? İmleçler veya T-SQL veya saklı yordam kullanmadan. LIMIT için her iki bağımsız değişkeni de desteklemek zorundadır , hem count hem de ofset. Geçici bir tablo kullanan çözümler de kabul edilemez.

Düzenle:

MS SQL Server 2000 için en yaygın çözüm gibi görünüyor aşağıda, örneğin 50'den 75'e kadar satırlar almak için:

SELECT TOP 25 *
FROM ( 
  SELECT TOP 75 *
  FROM   table 
  ORDER BY BY field ASC
) a 
ORDER BY field DESC;

ancak, toplam sonuç kümesi 60 satır ise bu işe yaramıyor. İç sorgu, üst 75 olduğu için 60 satır döndürür. Daha sonra dış sorgu, 50-75'in istenen "sayfasına" sığmayan 35-60 satırlarını döndürür. Temel olarak, bu çözüm, sayfa boyutunun bir katı olmayan bir sonuç kümesinin son "sayfasına" ihtiyacınız olmadıkça çalışır.

Düzenle:

başka bir çözüm daha iyi çalışır, ancak yalnızca sonuç kümesinin benzersiz bir sütun içerdiğini varsayabilirseniz:

SELECT TOP n *
FROM tablename
WHERE key NOT IN (
    SELECT TOP x key
    FROM tablename
    ORDER BY key
);

sonuç:

MS SQL Server 2000'de LIMIT taklit etmek için genel amaçlı bir çözüm yok gibi görünüyor. MS SQL Server 2005'te ROW_NUMBER() işlevini kullanabiliyorsanız iyi bir çözüm var.

38
tarihinde sordu Bill Karwin 2008-10-19 21:05:16
kaynak

4 ответов

burada sadece SQL Server 2005 ve daha yeni çalışır başka bir çözümdür çünkü except deyimi kullanır. Ama yine de paylaşıyorum. Eğer 50 - 75 yazma kayıtları almak istiyorsanız:

select * from (
    SELECT top 75 COL1, COL2
    FROM MYTABLE order by COL3
) as foo
except
select * from (
    SELECT top 50 COL1, COL2
    FROM MYTABLE order by COL3
) as bar
5
cevap Florian Fankhauser 2009-06-23 17:07:47
kaynak
SELECT TOP n *
FROM tablename
WHERE key NOT IN (
    SELECT TOP x key
    FROM tablename
    ORDER BY key
    DESC
);
5
cevap bostaf 2012-07-19 15:40:03
kaynak

yalnızca sınıra ihtiyacınız olduğunda, MS sql eşdeğer üst anahtar sözcüğe sahiptir, böylece açıktır. Ofset ile sınıra ihtiyacınız olduğunda, daha önce tarif edilen gibi bazı kesmek deneyebilirsiniz, ancak hepsi bir şekilde sipariş vermek için, yani bir şekilde ve daha sonra diğeri veya expencive operasyonda değil. Tüm bu cascades gerek yok sanırım. Oppinion'umdaki en temiz çözüm, SQL tarafında ofset olmadan TOP kullanmak ve daha sonra uygun olan gerekli başlangıç kaydını aramak olacaktır php'de mssql_data_seek gibi istemci yöntemi. Bu saf bir SQL çözümü olmasa da, bunun en iyisi olduğunu düşünüyorum çünkü herhangi bir ek yükü eklemiyor (eğer sizi endişelendiren şey buysa, onları geçtiğinizde atlanan kayıtlar ağda aktarılmayacaktır).

4
cevap 2009-05-13 14:06:24
kaynak

bunu ORM'DE oldukça basit olduğu için uygulamaya çalışacağım. Gerçekten SQL Server'da olması gerekiyorsa, aşağıdaki lınq to SQL deyimi için lınq to sql tarafından oluşturulan koda bakıp oradan gideceğim. Bu kodu uygulayan MSFT Mühendisi, SQL ekibinin bir parçasıydı ve ne yaptığını biliyordu.

var result = myDataContext . Aman Tanrım.Skip(pageındex * pageSize).Al (pageSize)

0
cevap Barka 2011-06-22 21:37:56
kaynak