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

Có thể lưu trữ giá trị của một cột đã chọn và sử dụng nó cho cột tiếp theo không?

Bạn cần CROSS APPLY ở đây, nó có thể tham chiếu đến các tham chiếu bên ngoài, không cần truy vấn con hoặc CTE phiền phức:

select col1, col2
from table1 as outer_table

-- can also have multi-row values
cross apply (values (complex_expression_1) ) as v1 (col1)
cross apply (values (expression_referring_to_col1) ) as v2 (col2)

-- alternate syntax, select without from returns a single row
cross apply (select complex_expression_1 as col1 ) AS v1
cross apply (select expression_referring_to_col1 as col2 ) as v2

-- you can also do anything you like in there, can be one or multiple rows
cross apply (
    select complex_expression_1 as col1 
    from othercomplexjoin as o
    where o.join_column = outer_table.join_column
) AS v1

Một số thủ thuật khác mà bạn có thể thực hiện với APPLY :

1. 1 trên mỗi nhóm của bảng con:

Giải pháp cổ điển cho "top 1 mỗi nhóm" là sử dụng row_number() . Điều này thường có thể dẫn đến việc quét rất lớn, đặc biệt khi số lượng các giá trị bên ngoài khác biệt so với bảng con là nhỏ.

select
    o.id,
    lastPayment.Date
from order_header as o
join
( select *, row_number() over (partition by order_id order by date desc) as rn
 from payments
) as lastPayment on ...
where lastPayment.rn = 1

Thay vào đó, chúng ta có thể làm:

select
    o.id,
    lastPayment.Date
from order_header as o
cross apply
( select top (1) *
 from payments as p
 where p.order_id = o.id
 order by date desc
) as lastPayment

Lưu ý:OUTER APPLY thay thế một cách khái niệm một phép nối bên trái, tức là trả về giá trị rỗng thay vì không có hàng.

2. Giải nén

select
    o.id,
    customer.*
from order_header as o
cross apply ( values    -- This returns two rows for every order_header
    ( 'DeliveryCustomer', o.deliveryCustomer ),
    ( 'billingCustomer', o.billingCustomer )
) as customer (type, name)

3. Bùng nổ một hàng với số lần thay đổi:

Giả sử chúng ta muốn lấy một lượng và chia nó thành các hàng khác nhau. Nếu amount <= 50 sau đó là một hàng amount , nếu > 50 sau đó là hai hàng, một trong số 50 và một trong các hàng còn lại:

select t.id, v.amount
from table as t
cross apply (
    select case when amount > 50 then 50 else amount end as amount
    union all
    select amount - 50   -- note this row will not appear if amount < 50
    where amount > 50
) v


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. làm thế nào để tách chuỗi thành các cột khác nhau?

  2. SQL Server Deadlock là gì?

  3. Cách vô hiệu hóa tất cả các ràng buộc về CHECK &khóa ngoại trong cơ sở dữ liệu trong SQL Server (Ví dụ T-SQL)

  4. Làm cách nào để tiện ích mở rộng SQLSRV hoạt động với PHP, vì MSSQL không được dùng nữa?

  5. Làm thế nào để xử lý deadlock Sql Server hiệu quả trong C # với ADO?