简体   繁体   中英

Alternative for sub-query in SQL?

I have query that should return few column results. Also there is one requirement where I have to apply additional filter for one of the columns. I found solution using sub-query (select inside of the main select) here is example:

SELECT 
   recid,
   price,
   receive_date,
   (SELECT deduction FROM Cost WHERE recid = c.recid AND status = 'Y') AS deduction
FROM Cost c
   INNER JOIN cost_types ct
      c.recid = ct.recid
WHERE cost_year = '2018'

Query above has to pull all records from the Cost table that match cost_type table records and where cost_year is 2018 . On top of that I have to filer deduction where status is Y . I'm wondering what other technique I can use for this query? I know about UNION / UNION ALL but that is more code and seems redundant. If anyone have suggestions or better way to approach this situation please let me know. Also, I was wondering if this would be a better fit for Stored Procedure? Would that be recommended?

A JOIN would be the normal method, something like this:

SELECT c.recid, c.price, c.receive_date,
       cd.deduction
FROM cost c INNER JOIN
     cost_types ct
     ON c.recid = ct.recid LEFT JOIN
     cost cd
     ON cd.recid = c.recid AND cd.status = 'Y'
WHERE c.cost_year = 2018;

This is guessing where the columns are coming from. Adjust the qualifiers if the columns come from different tables.

You can probably also use a window function:

SELECT c.recid, c.price, c.receive_date,
       SUM(CASE WHEN c.status = 'Y' THEN c.deduction END) OVER (PARTITION BY c.recid) as deduction
FROM cost c INNER JOIN
     cost_types ct
     ON c.recid = ct.recid 
WHERE c.cost_year = 2018;

Why not simply use CASE ?:

SELECT recid, price, receive_date,
      (CASE WHEN status = 'Y' THEN deduction END) AS deduction
FROM Cost c INNER JOIN 
     cost_types ct
     ON c.recid = ct.recid 
WHERE cost_year =  2018;

EDIT : I suspect you want something :

SELECT recid, price, receive_date, c1.deduction 
FROM Cost c INNER JOIN 
     cost_types ct
     ON c.recid = ct.recid OUTER APPLY 
     (SELECT TOP (1) c1.*
      FROM  Cost c1
      WHERE c1.recid = c.recid AND c1.status = 'Y'
      ORDER BY ?? -- Use ordering column based on you want deduction 
     ) c1;
WHERE cost_year =  2018;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM