简体   繁体   中英

How to select a sub-query with MySQL using the WHERE part?

I have 2 tables which look like:

The money table looks like the following:

id  type     cash
1   54       3.23
2   293      1.12
3   181      4.00

The plus table looks like the following:

id   money_id bonus
1    3         0.50
2    2         0.10

What I basically want is to select ALL data from the money table, including money.cash with the added bonus from the plus table, if they have any, and I want to select only those records, which have more than 1.50 cash (including the bonus).

So the result I'd like to achieve is:

id  type     cash_full
1   54            3.23
2   181           4.50

I have tried to make some query, but it always says error, when I want to include the cash_full into the WHERE statement. Other than that, it's working flawlessly, I just can't filter the query with the cash_full column.

SELECT mo.*,
IFNULL
(
    mo.cash + 
    (
    SELECT bonus 
    FROM plus as pu 
    WHERE mo.id = pu.money_id
    ), mo.cash
) as cash_full
FROM `money` as mo 
WHERE cash_full >= 1.5

So how is it possible that this query is not working? Is there any solution for my problem?

1. Assuming you can have more than one bonus per money id :

You can use an alias in an having clause (with mysql), after having grouped the values from money table

select mo.id, mo.type,  mo.cash + sum(coalesce(p.bonus, 0)) as cash_full
from money mo
left join plus p on p.money_id = mo.id
group by mo.id, mo.type, mo.cash
having cash_full > 1.5

with other db, you would have to use a subquery, or repeat the "aliased" operation in the having clause : something like

having mo.cash +  sum(coalesce(p.bonus, 0)) > 1.5

see SqlFiddle

2. Assuming you can't have more than one bonus per money id

You can do a subquery to avoid repeating the "addition"*

select id, type, cash_full
from (
   select mo.id, mo.type, mo.cash + coalesce(p.bonus, 0) as cash_full
   from money mo
   left join plus p on p.money_id = mo.id) s
where cash_full > 1.5;

A simple LEFT JOIN will do it:-

SELECT a.id, a.type, a.cash + IFNULL(SUM(b.bonus), 0) AS cash_bonus
FROM money a 
LEFT OUTER JOIN plus b
ON a.id = b.money_id
GROUP BY a.id, a.type
HAVING cash_bonus > 1.50

Note that this is a bit strange as it has a non aggregate field that isn't in the GROUP BY clause. This should be fine in MySQL but might cause issues in other flavours of SQL. In which case a LEFT JOIN to a sub query might be necessary:-

SELECT a.id, a.type, a.cash + IFNULL(b.tot_bonus, 0) AS cash_bonus
FROM money a 
LEFT OUTER JOIN 
(
    SELECT money_id, SUM(bonus) AS tot_bonus
    FROM plus 
    GROUP BY money_id
) b
ON a.id = b.money_id
WHERE a.cash + IFNULL(b.tot_bonus, 0) > 1.50

Try this...

select mo.*,sum(mo.cash+ IFNULL(pl.cash_full,0)) as cash_full from money mo
LEFT JOIN plus pl on pl.money_id=mo.id and pl.cash_full >=1.5

I think this might help you

select m.id, m.type, (m.cash + p.bonus) as cash_full from money m, plus p WHERE m.id=p.money_id;

Here is the SQLFiddle to have a look

SELECT mo.*, (mo.cash + IFNULL(p.bonus,0)) AS cash_full
FROM `money` as mo 
LEFT JOIN `plus` AS p
ON p.money_id = mo.id
WHERE cash_full >= 1.5

Try this:

select m.*, (IFNULL(p.bonus,0)+ m.cash) as cash_full
from money m left join plus p
on m.id = p.id
and cash_full >= 1.50

If you are using SQL Server/MS Access use ISNULL, Oracle use NVL, My SQL use IFNULL.

SELECT 
  M.ID, 
  M.TYPE, 
  M.CASH, 
  IFNULL(P.BONUS, 0) AS BONUS, 
  M.CASH + IFNULL(P.BONUS, 0) AS TOTAL   
FROM
  MONEY M
  LEFT JOIN PLUS P ON
    P.MONEY_ID = M.ID
WHERE
  M.CASH + IFNULL(P.BONUS, 0) >= 1.5

SqlFiddle

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