JOIN table if condition is satisfied, else perform no join

ⅰ亾dé卋堺 提交于 2021-01-29 16:54:23

问题


I have one table transaction and another table transaction_item.

One transaction has multiple transaction_items.

I want to left join transaction_item if transaction_item.amount >= 2, else perform no join.

select ti.*
from transaction t
LEFT JOIN transaction_item ti on ti.unique_id = t.unique_id  
    AND ti.location_id =  t.location_id 
    AND ti.transaction_date = t.transaction_date
    AND ti.amount >= 2
where t.pos_transaction_id = 4220
and t.location_id = 1674
and t.transaction_date = '2020-05-08';

If I do it this way it is results in 15 rows in place of total 20 rows, because 20 rows are in transaction_item table corresponding to transaction_id 4220. But I want no join in this case because 5 rows in transaction_item have amount < 2.


回答1:


Your description a bit confusing, but the title says:
"else perform no join"

So I think you want something this:

SELECT ti.*
FROM   transaction t
LEFT   JOIN transaction_item ti ON ti.unique_id        = t.unique_id  
                               AND ti.location_id      = t.location_id 
                               AND ti.transaction_date = t.transaction_date
                               AND NOT EXISTS (
                                    SELECT FROM transaction_item tx
                                    WHERE  tx.unique_id        = t.unique_id  
                                    AND    tx.location_id      = t.location_id 
                                    AND    tx.transaction_date = t.transaction_date
                                    AND    tx.amount < 2)  -- !
WHERE  t.pos_transaction_id = 4220
AND    t.location_id = 1674
AND    t.transaction_date = '2020-05-08';

However, the LEFT JOIN in combination with only columns from the right table in the SELECT list is dubious at best. This way you get one row with all NULL values for every row in transaction that qualifies and has no matching rows in transaction_item or one or more matching rows with amount < 2. I doubt you want that.

Typically, you'll want to include columns from transaction in the SELECT list, or use an [INNER] JOIN instead.

So it could be:

SELECT ti.*
FROM   transaction t
JOIN   transaction_item ti USING (unique_id, location_id, transaction_date)
WHERE  t.pos_transaction_id = 4220
AND    t.location_id = 1674
AND    t.transaction_date = '2020-05-08';
AND    NOT EXISTS (
   SELECT FROM transaction_item tx
   WHERE  tx.unique_id        = t.unique_id  
   AND    tx.location_id      = t.location_id 
   AND    tx.transaction_date = t.transaction_date
   AND    tx.amount < 2);

Then again, a table transaction_item would typically have a FK column transaction_id referencing transaction - in which case we can simplify

SELECT ti.*
FROM   transaction t
JOIN   transaction_item ti ON ti.transaction_id = t.transaction_id -- ?
WHERE  t.pos_transaction_id = 4220
AND    t.location_id = 1674
AND    t.transaction_date = '2020-05-08';
AND    NOT EXISTS (
   SELECT FROM transaction_item tx
   WHERE  tx.transaction_id = t.transaction_id
   AND    tx.amount < 2);

You mentioned both pos_transaction_id and transaction_id, so I am guessing here ...

The major insight to take away from this: always show exact table definitions with any such question.



来源:https://stackoverflow.com/questions/62300612/join-table-if-condition-is-satisfied-else-perform-no-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!