问题
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