Multiply output of subquery (MySQL) - mysql

I'm trying to multiply the result of a subquery with a field from the 'main' query. See the following example:
Table: subscriptions
id
title
price
Table: users
subscription_id
SELECT
subscriptions.id,
subscriptions.title,
(select count(*) from users where users.subscription_id = subscriptions.id) AS qty
SUM(qty * subscriptions.price) AS total
FROM subscriptions
This gives the error Unknown column 'qty' in 'field list'. So it seems like the result from the subquery isn't available in the SELECT field. After searching StackOverflow I found some of the same questions and it seems I need to move the subquery from the select to a JOIN. This seems simple enough but I'm having trouble to modify my own query to work like this. Anyone who can push me in the right direction?

Don't put the subquery in the SELECT list, join with it.
SELECT s.id, s.title, u.qty, s.price * u.qty AS total
FROM subscriptions AS s
JOIN (
SELECT subscription_id, COUNT(*) AS qty
FROM users
GROUP BY subscription_id
) AS u ON s.id = u.subscription_id

Almost right.
SELECT
s.id,
s.title,
SUM(s.price * (select count(*) from users u where u.subscription_id = s.id)) AS total
FROM subscriptions s
GROUP BY s.id, s.title

I tried to reslove your query, check it
https://dbfiddle.uk/xrMrT7Y4
I don't know why someone has deleted my answer. Here I found issue in your query is you didn't group the aggregate function & If you are comparing ID then both tables should be considered. #Vinze

Related

MySQL SUM() with JOIN and LIMIT

The concerned schema and query is on SQL fiddle here http://sqlfiddle.com/#!2/312d3/16
The JOIN query below gets the result that I want.
SELECT p.*, payer.username as payer_username, payee.username as
payee_username FROM (`payments_history` p) JOIN (SELECT * FROM users)
AS payer ON `payer`.`user_id` = `p`.`payer_id` JOIN (SELECT * FROM
users) AS payee ON `payee`.`user_id` = `p`.`payee_id` ORDER BY
`p`.`created_timestamp`;
Doing a sum() on the "p.amount" column for all the rows works fine too.
SELECT SUM(p.amount) FROM (`payments_history` p) JOIN (SELECT * FROM
users) AS payer ON `payer`.`user_id` = `p`.`payer_id` JOIN (SELECT *
FROM users) AS payee ON `payee`.`user_id` = `p`.`payee_id` ORDER BY
`p`.`created_timestamp`;
But doing a sum() on the same column for the rows on each page (offset,limit) returns an empty result (I would like to have the total of the "amount" column for the rows on each page).
SELECT SUM(p.amount) FROM (`payments_history` p) JOIN (SELECT * FROM
users) AS payer ON `payer`.`user_id` = `p`.`payer_id` JOIN (SELECT *
FROM users) AS payee ON `payee`.`user_id` = `p`.`payee_id` ORDER BY
`p`.`created_timestamp` limit 0,2;
Also in the sum() query, when the offset starts from anything greater than 0 (try LIMIT 2,2), it returns an empty result.
What am I doing wrong?.
Thank you.
Give this a try:
SELECT SUM(l.amount) FROM (
SELECT p.amount FROM payments_history p
INNER JOIN users payer ON payer.user_id=p.payer_id
INNER JOIN users payee ON payee.user_id=p.payee_id
ORDER BY p.created_timestamp
LIMIT 0,10
) l
I'm not sure if you plan to add other fields to the query, or have further conditions in a WHERE clause, but having those joins in there doesn't seem all that useful right now.
Your question is just a little vague. What will be on the page that you want to have sums on? Is it a report for the specific user? If so, then you can just add a WHERE clause to your query to limit the sum to just that user. Something like:
SELECT SUM(p.amount)
FROM (`payments_history` p)
JOIN (SELECT * FROM users) AS payer ON `payer`.`user_id` = `p`.`payer_id`
JOIN (SELECT * FROM users) AS payee ON `payee`.`user_id` = `p`.`payee_id`
WHERE payer.user_id = [the user id]
ORDER BY `p`.`created_timestamp`;
If that's not what you want, then you may want to clarify the question a little bit. It's unclear.
Question:
Are you trying to get the sum of just one row? (your answer in the comments makes it seem that way) If so, that's just the value in the amount. You can't sum a single value.

MySQL Group two column with where clause on both two group

What I have:
I have two table , first is user_faktorha save invoices data and second is u_payment save payment data .
What I want:
I want to group all data from this two table and have a result as one table with sum both table.
My two table with sample query's is on sqlfiddle : http://sqlfiddle.com/#!2/b9f9e/4
What's problem:
I try to solve this problem , but give wrong result each time , for example (can be see on sqlfiddle) , user/tell named as habib on give wrong sum(price) result.
habib's faktorhaprice = -508261 and habib's paymentprice = 648000 but sum result in main query have wrong data -7115654 and 13000000
what's the solution ?
(Updated) One way:
SELECT tell,SUM(FAKTORHAPRICE) FAKTORHAPRICE, SUM(PaymentPrice) PaymentPrice
FROM (SELECT tell, price as FAKTORHAPRICE, null PaymentPrice
from user_faktorha
union all
SELECT Username as tell, null as FAKTORHAPRICE, Price as PaymentPrice
FROM `u_payment` WHERE Active='1') sq
GROUP BY tell ORDER BY FAKTORHAPRICE ASC;
SQLFiddle here.
The essence of your problem here is that you are trying to relate to unrelated tables. Sure they have common data in the user name, but there is not a clean relation between them like an invoice id that can be used to relate the items together such that the OUTER JOIN wouldn't duplicate records in your result set. My suggestion would be to do the aggregation on each table individually and then join the results like this:
SELECT f.tell, f.faktorhaprice, p.paymentprice
FROM
(SELECT tell, SUM(price) AS faktorhaprice FROM user_faktorha GROUP BY tell) AS f
INNER JOIN
(SELECT username, SUM(price) AS paymentprice FROM u_payment GROUP BY username) AS p
ON f.tell = p.username

mysql select count union

I have something like this:
(SELECT COUNT(*) AS total FROM `transactions` WHERE
`asset`='u_{$user_id}' GROUP BY id)
UNION DISTINCT
(SELECT COUNT(*) AS total FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}'
GROUP BY tr.id)
It gives 1
Now works like this:
SELECT
(SELECT COUNT(*) FROM `transactions`
WHERE `asset`='u_{$user_id}')
+
(SELECT COUNT(*) FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}')
It gives 6
But i need to get 5.., sow how to make a right query?
Sure, i can do this by php, but..HOW by sql..?
Really "and" and "or" conditions does not matter, they works correctly, the problem is in counting UNION`ed query. The second query correctly counts summ (1+5), but values ​​intersect queries. The first one gives result of just first subquery. So, i need to unique results before count...
In php, it should look like that: i get transactions id list by inner join with payments, than construct a long query in a loop, to get something like SELECT COUNT(*) FROM transactions WHERE (*what i have now* OR id=$id_1 OR id=$id_2 OR id=$id_3 etc..)
UPD: cutted
RESOLVED!=)
SELECT COUNT(*) FROM(
SELECT tr.* FROM transactions tr
WHERE tr.asset='u_{$user_id}' OR (tr.liability='g' AND tr.l_info='{$user_name}')
UNION SELECT tr.* FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}' AND pa.status='100')
AS total
AS total is importantly!
I gone through your question, and i think you want to fetch the maximum from the union clause, well i am not aware of the mySql, so i have solved your question in MS-SQL.
Logic:- I have used CTE, and afterwards performed UNION operation and then i have selected MAXIMUM from the two.
WITH COUNTT AS (SELECT 1 AS TEST
UNION
SELECT 5 AS TEST)
SELECT MAX(TEST) FROM COUNTT
And, in place of hardcoded "1" and "5", you can use your count query, i think it is what you are looking for. And, please mark it as an answer.

valid MySQL subquery syntax and placement

I've never figured out several syntax things about SQL subqueries. Mainly I'm interested in where in the parent query is it valid to place a subquery.
here's an example which throws an error:
SELECT
sum(votes.vote) AS sum,
votes.vote IS NOT NULL AS did_i_vote,
purchase_id, subject, full_name
FROM (
SELECT vote FROM votes
where votes.acct_id=3 AND
votes.column_name='purchase_id'
) votes
RIGHT JOIN items_purchased
ON votes.parent_id=items_purchased.purchase_id
JOIN accounts
ON items_purchased.purchaser_account_id=accounts.acct_id
JOIN items
ON items_purchased.item_id=items.folder_id
WHERE purchase_id='2'
GROUP BY items_purchased.purchase_id
How do I make this query work?
One error is in the GROUP BY part!
In the SELECT, you can only have the columns displayed in the GROUP BY and agregate functions of columns that are not there.
Check THIS info!
Your subquery must select every column that you wish to reference afterwards.
SELECT
sum(votes.vote) AS sum,
votes.vote IS NOT NULL AS did_i_vote,
purchase_id, subject, full_name
FROM (
SELECT vote, parent_id FROM votes
where votes.acct_id=3 AND
votes.column_name='purchase_id'
) votes
RIGHT JOIN items_purchased
ON votes.parent_id=items_purchased.purchase_id
JOIN accounts
ON items_purchased.purchaser_account_id=accounts.acct_id
JOIN items
ON items_purchased.item_id=items.folder_id
WHERE purchase_id='2'
GROUP BY items_purchased.purchase_id
Is what I would assume (note that I select vote and parent_id in the subquery)

Subquery returns more than 1 row

im geting this error when trying to do 2 counts inside of my query
first ill show you the query:
$sql = mysql_query("select c.id, c.number, d.name,
(select count(*) from `parts` where `id_container`=c.id group by `id_car`) as packcount,
(select count(*) from `parts` where `id_container`=c.id) as partcount
from `containers` as c
left join `destinations` as d on (d.id = c.id_destination)
order by c.number asc") or die(mysql_error());
now the parts table has 2 fields that i need to use in the count:
id_car
id_container
id_car = the ID of the car the part is for
id_container = the ID of the container the part is in
for packcount all i want is a count of the total cars per container
for partcount all i want it a count of the total parts per container
It's because of GROUP BY You're using
Try something like
(select count(distinct id_car) from `parts` where `id_container`=c.id)
in You're subquery (can't check right now)
EDIT
PFY - I think UNIQUE is for indexes
Your grouping in your first sub-query is causing multiple rows to be returned, you will probably need to run separate queries to get the results you are looking for.
This subquery may return more than one row.
(select count(*) from `parts` where `id_container`=c.id group by `id_car`) as packcount, ...
so, i'd suggest to try something of the following:
(select count(DISTINCT `id_car`) from `parts` where `id_container`=c.id) as packcount, ...
see: COUNT(DISTINCT) on dev.mysql.com
and: QA on stackoverflow