Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Mungkinkah menyimpan nilai dari satu kolom pilih dan menggunakannya untuk yang berikutnya?

Anda membutuhkan CROSS APPLY di sini, ini dapat merujuk ke referensi luar, tidak diperlukan subquery atau CTE yang mengganggu:

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

Beberapa trik lagi yang dapat Anda lakukan dengan APPLY :

1. 1 teratas per grup tabel anak:

Solusi klasik untuk "1 teratas per grup" adalah dengan menggunakan row_number() . Ini sering kali dapat menghasilkan pemindaian yang besar, terutama bila jumlah nilai luar yang berbeda relatif kecil dibandingkan tabel anak.

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

Sebagai gantinya kita dapat melakukan:

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

Catatan:OUTER APPLY secara konseptual menggantikan gabungan kiri, yaitu mengembalikan nol alih-alih tanpa baris.

2. Membatalkan putaran

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. Meledak satu baris beberapa kali variabel:

Katakanlah kita ingin mengambil jumlah, dan membaginya menjadi beberapa baris. Jika amount <= 50 lalu satu baris amount , jika > 50 lalu dua baris, satu dari 50 dan satu lagi:

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. SQL Server memeriksa sensitivitas huruf besar-kecil?

  2. Sisipkan beberapa baris TANPA mengulangi bagian INSERT INTO ... dari pernyataan?

  3. Cara membagi nilai yang dipisahkan koma ke kolom

  4. Bagaimana menjalankan kueri yang sama pada semua database pada sebuah instance?

  5. Menerapkan relasi satu-ke-nol-atau-satu di SQL Server