Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Funkcja wartościami z tabeli — kolejność według jest ignorowana na wyjściu

W twoim pierwotnym podejściu były dwie rzeczy niewłaściwe.

  1. Przy wstawianiu do tabeli nigdy nie było zagwarantowane, że ORDER BY na INSERT ... SELECT ... ORDER BY to kolejność, w jakiej wiersze zostały faktycznie wstawione.
  2. Po wybraniu z niego SQL Server nie gwarantuje, że SELECT bez ORDER BY i tak zwróci wiersze w dowolnej kolejności, na przykład w kolejności reklamowej.

W 2012 wygląda na to, że zachowanie zmieniło się w stosunku do pozycji 1. Teraz generalnie ignoruje ORDER BY na SELECT instrukcja będąca źródłem INSERT

DECLARE @T TABLE(number int)

INSERT INTO @T 
SELECT number
FROM master..spt_values
ORDER BY name

Plan 2008

Plan 2012

Powodem zmiany zachowania jest to, że w poprzednich wersjach SQL Server generował jeden plan, który był współdzielony między wykonaniami z SET ROWCOUNT 0 (off) i SET ROWCOUNT N . Operator sortowania był tam tylko po to, aby zapewnić poprawną semantykę w przypadku, gdy plan został uruchomiony przez sesję z niezerowym ROWCOUNT ustawić. TOP operator po lewej stronie to ROWCOUNT TOP .

SQL Server 2012 tworzy teraz oddzielne plany dla dwóch przypadków, więc nie ma potrzeby dodawania ich do ROWCOUNT 0 wersja planu.

Sortowanie może nadal pojawiać się w planie w 2012 roku, jeśli SELECT ma wyraźny TOP zdefiniowane (inne niż TOP 100 PERCENT ), ale nadal nie gwarantuje to rzeczywistej kolejności wstawiania wierszy, plan może mieć wtedy inne sortowanie po TOP N jest ustanowiona, aby na przykład uporządkować wiersze w kolejności indeksu klastrowego.

Na przykład w twoim pytaniu po prostu dostosowałbym kod wywołujący, aby określić ORDER BY name jeśli tego wymaga.

Odnośnie Twojego sort_id pomysł Gwarancje zamawiania w SQL Server jest to gwarantowane przy wstawianiu do tabeli z IDENTITY że kolejność ich przydzielania będzie zgodna z ORDER BY więc możesz też zrobić

DECLARE @Customer TABLE (
  Sort_Id     INT IDENTITY PRIMARY KEY,
  Customer_ID INT,
  Name        INT,
  Expired     BIT )

INSERT INTO @Customer
SELECT Customer_ID,
       Name,
       CASE
         WHEN Expiry_Date < Getdate() THEN 1
         WHEN Expired = 1 THEN 1
         ELSE 0
       END
FROM   Customer
ORDER  BY Name 

ale nadal musisz zamawiać według sort_id w zapytaniach wybierających, ponieważ bez tego nie ma gwarantowanej kolejności (być może ten sort_id podejście może być przydatne w przypadku, gdy oryginalne kolumny użyte do zamówienia nie są kopiowane do zmiennej tabeli)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Używając SSIS, jak znaleźć miasta o największej liczbie mieszkańców?

  2. Zrozumienie rozmiaru pamięci „datetimeoffset” w SQL Server

  3. SQL:pisz tylko na pierwszą literę

  4. Zadanie SQL Agent:Określ, jak długo działa

  5. Kursor SQL w zawartości dynamicznej