Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

SQL Server:hàng có trong một truy vấn, bị thiếu trong một truy vấn khác

Minh chứng cho lời giải thích khả thi.

Tạo tập lệnh bảng

SELECT *
INTO #T
 FROM master.dbo.spt_values

 CREATE NONCLUSTERED INDEX [IX_T] ON  #T ([name] DESC,[number] DESC);

Truy vấn một (Trả về 35 kết quả)

WITH cte AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY NAME) AS rn
 FROM  #T
)
SELECT c1.number,c1.[type] 
FROM cte c1
JOIN cte c2 ON c1.rn=c2.rn AND c1.number <> c2.number

Truy vấn thứ hai (Tương tự như trước đây nhưng thêm c2. [type] vào danh sách chọn khiến nó trả về 0 kết quả) ;

WITH cte AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY NAME) AS rn
 FROM  #T
)
SELECT c1.number,c1.[type] ,c2.[type] 
FROM cte c1
JOIN cte c2 ON c1.rn=c2.rn AND c1.number <> c2.number

Tại sao?

row_number () cho các NAME trùng lặp không được chỉ định vì vậy nó chỉ chọn bất kỳ cái nào phù hợp với kế hoạch thực thi tốt nhất cho các cột đầu ra được yêu cầu. Trong truy vấn thứ hai, điều này giống nhau đối với cả hai lệnh gọi cte, trong truy vấn đầu tiên, nó chọn một đường dẫn truy cập khác với kết quả là row_numbering khác nhau.

Giải pháp được đề xuất

Bạn đang tự tham gia CTE trên ROW_NUMBER() over (order by t.[Date])

Trái ngược với những gì có thể mong đợi, CTE có thể sẽ không được hiện thực hóa điều này sẽ đảm bảo tính nhất quán cho tự kết hợp và do đó bạn giả sử có mối tương quan giữa ROW_NUMBER() ở cả hai mặt mà có thể không tồn tại đối với các bản ghi có [Date] trùng lặp tồn tại trong dữ liệu.

Điều gì sẽ xảy ra nếu bạn thử ROW_NUMBER() over (order by t.[Date], t.[id]) để đảm bảo rằng trong trường hợp các ngày bị ràng buộc, đánh số hàng theo thứ tự nhất quán được đảm bảo. (Hoặc một số cột / tổ hợp cột khác có thể phân biệt các bản ghi nếu id không thực hiện được)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Vấn đề truy vấn Sql 2008 - LatLong nào tồn tại trong một đa giác địa lý?

  2. Kích hoạt chèn các giá trị cũ- giá trị đã được cập nhật

  3. Cách khắc phục “Không thành công câu lệnh ALTER TABLE SWITCH” Msg 4982 (SQL Server)

  4. SQL Server, sử dụng bảng làm hàng đợi

  5. Làm cách nào để gọi một thủ tục được lưu trữ với các đối số bằng sqlcmd.exe?