MySQL query on multiple tables - mysql

Greets! I have 12 tables, one for each month of the year:
January
+----+-----+
| id | sale|
+----+-----+
| 1 | 250 |
| 3 | 500 |
| 5 | 200 |
| 7 | 100 |
+----+-----+
February
+----+-----+
| id | sale|
+----+-----+
| 1 | 350 |
| 2 | 400 |
| 3 | 500 |
| 4 | 800 |
+----+-----+
etc.
I need to do a query where the result is something like this:
Annual Sales
+----+-----------+-----------+
| id | Sales_Jan | Sales_Feb |
+----+-----------+-----------+
| 1 | 250 | 350 |
| 2 | 0 | 400 |
| 3 | 500 | 500 |
| 4 | 0 | 800 |
| 5 | 200 | 0 |
| 7 | 100 | 0 |
+----+-----------+-----------+
Where the matching ids from both tables do not duplicate and the missing ids from other months are shown by putting a 0 or any other symbol indicating that there was not any sales that month from that id.
Thank you very much!

You can approach this using union all and aggregation:
select id,
sum(case when month = 'Jan' then sale else 0 end) as Jan_Sale,
sum(case when month = 'Feb' then sale else 0 end) as Feb_Sale,
. . .
sum(case when month = 'Dec' then sale else 0 end) as Dec_Sale
from ((select 'Jan' as month, id, sale from January) union all
(select 'Feb' as month, id, sale from February) union all
. . .
(select 'Dec' as month, id, sale from February)
) t
group by id;

Related

Group data by foreign key and date with total by date

I need help to select daily payments made and group by the organization and date.
Group by date, then the total number of payments and the sum total amount of payments for each day
Tables are as follows,
organizations
-----------------------------
| id | name |
+-------------+-------------+
| 1 | org_1 |
+-------------+-------------+
| 2 | org_2 |
+-------------+-------------+
| 3 | org_2 |
-----------------------------
payments
------------------------------------------------------------
| id | org_id | amount | date_created |
+-----------+------------+-------------+-------------------+
| 1 | 2 | 20 | 2020-11-06 |
+-----------+------------+-------------+-------------------+
| 2 | 2 | 10 | 2020-11-06 |
+-----------+------------+-------------+-------------------+
| 3 | 1 | 50 | 2020-11-05 |
+-----------+------------+-------------+-------------------+
| 4 | 2 | 10 | 2020-11-05 |
------------------------------------------------------------
Expected Result
----------------------------------------------------------------------------------------------
| date_created | total_amount | num_payments | org_1 | org_2 | org_3 |
+----------------+----------------+-------------------+-----------+-------------+------------+
| 2020-11-06 | 30.00 | 2 | 0 | 2 | 0 |
+----------------+----------------+-------------------+-----------+-------------+------------+
| 2020-11-05 | 60.00 | 2 | 1 | 1 | 0 |
+----------------+----------------+-------------------+-----------+-------------+------------+
Use conditional aggregation:
select p.date_created,
sum(p.amount) as total_amount,
count(*) as num_payments,
sum(case when o.name = 'org_1' then p.amount else 0 end) as org_1,
sum(case when o.name = 'org_2' then p.amount else 0 end) as org_2,
sum(case when o.name = 'org_3' then p.amount else 0 end) as org_3
from payments p
inner join organizations o on o.id = p.org_id
group by p.date_created

How to get highest value for each group by checking with two columns value

I have this table test_table below
USER_ID | YEAR | MONEY
----------------------
1 | 0 | 0
1 | 12 | 12
1 | 48 | 12
2 | 15 | 15
2 | 10 | 20
3 | 0 | 0
So I am trying to return the row which has the highest money. For example, the row return would be like this
USER_ID | YEAR | MONEY
----------------------
1 | 12 | 12
1 | 48 | 12
2 | 10 | 20
3 | 0 | 0
But because User ID 1 has the same value for money, I would like to check for the highest year of that money amount and return the result. The expected result should be
USER_ID | YEAR | MONEY
----------------------
1 | 48 | 12
2 | 10 | 20
3 | 0 | 0
Is it possible to get row like this?
Here is the link to test your query online
http://sqlfiddle.com/#!9/2e5660/1
You can try using correlated subquery
DEMO
select userid, moneyval,max(year) as year
from
(
select * from t a
where moneyval in
(select max(moneyval) from t b where a.userid=b.userid)
)A group by userid, moneyval
OUTPUT:
userid moneyval year
1 12 48
2 20 10
3 0 0
You can use not exists to get the rows with maximum values in money (and year):
select t.*
from test_table t
where not exists (
select 1 from test_table
where userid = t.userid and (
money > t.money or (money = t.money and year > t.year)
)
)
See the demo.
Results:
| userid | money | year |
| ------ | ----- | ---- |
| 1 | 12 | 48 |
| 2 | 20 | 10 |
| 3 | 0 | 0 |

How to SUM values for DISTINCT values of another column and GROUP BY date?

How can we SUM amount for each activity only on same date and output a row for each date? This query is not working.
SELECT SUM(amount), type, date FROM table GROUP BY DISTINCT date;
Table
+----+------------+-----------+---------+
| id | date | activity | amount |
+----+------------+-----------+---------+
| 1 | 2017-12-21 | Shopping | 200 |
| 2 | 2017-12-21 | Gift | 240 |
| 3 | 2017-12-23 | Give Away | 40 |
| 4 | 2017-12-24 | Shopping | 150 |
| 5 | 2017-12-25 | Give Away | 120 |
| 6 | 2017-12-25 | Shopping | 50 |
| 7 | 2017-12-25 | Shopping | 500 |
+----+------------+-----------+---------+
Required Result
+------------+-----------+------+-----------+
| date | Shopping | Gift | Give Away |
+------------+-----------+------+-----------+
| 2017-12-21 | 200 | 240 | |
| 2017-12-23 | | | 40 |
| 2017-12-24 | 150 | | |
| 2017-12-25 | 550 | | 120 |
+------------+-----------+------+-----------+
Use:
select `date`,
sum(if (activity='Shopping', amount, null)) as 'Shopping',
sum(if (activity='Gift', amount, null)) as 'Gift',
sum(if (activity='Give Away', amount, null)) as 'Give Away'
from table
group by `date`
You can try this. It returns exact result that you want
SELECT t.date,
SUM(t.shopping_amount) AS shopping,
SUM(t.gift_amount) AS gift,
SUM(t.give_away_amount) AS give_away
FROM
(
SELECT p.`date`, p.`activity`, p.`amount` AS shopping_amount,
0 AS gift_amount, 0 AS give_away_amount
FROM products p
WHERE p.`activity` = 'Shopping'
UNION
SELECT p.`date`, p.`activity`, 0 AS shopping_amount,
p.amount AS gift_amount, 0 AS give_away_amount
FROM products p
WHERE p.`activity` = 'Gift'
UNION
SELECT p.`date`, p.`activity`, 0 AS shopping_amount,
0 AS gift_amount, p.amount AS give_away_amount
FROM products p
WHERE p.`activity` = 'Give Away'
) t
GROUP BY t.date
Hmmm, you can't pivot your results into column headers unless you know all possible values as demonstrated by slaasko but you can get the results using sql into a form which can be pivoted using your display tool ( e.g. slice of BI tool).
SELECT SUM(amount), activity, date FROM table GROUP BY date, activity;

Mysql Join Union Query By Date

I have 2 tables
and i want the result as this using join query. I don't have any Idea
Join Query By
TBL_SUCCESS_ORDER
------------------------
id | date | amount
-------------------------
1 | 2017-01-01 | 1000
2 | 2017-01-06 | 300
3 | 2017-01-29 | 50
4 | 2017-02-02 | 100
5 | 2017-02-16 | 400
6 | 2017-03-01 | 500
7 | 2017-04-03 | 1200
TBL_FAIL_ORDER
------------------------
id | date | amount
-------------------------
1 | 2017-01-03 | 400
2 | 2017-01-07 | 300
3 | 2017-01-24 | 50
4 | 2017-02-02 | 100
5 | 2017-04-07 | 200
RESULT
------------------------------------------------------------------
year | month | sum_of_succes_amount | sum_of_fail_amount | total
------------------------------------------------------------------
2017 | January | 1350 | 750 | 2100
2017 | Febuary | 500 | 100 | 600
2017 | March | 500 | 0 | 500
2017 | April | 1200 | 200 | 1400
I been stack for a whole week i did not get it . When i connect api json
TBL_PENDING_ORDER
------------------------
id | date | amount
-------------------------
1 | 2017-04-03 | 600
2 | 2017-05-07 | 600
RESULT
-----------------------------------------------------------------------------------------
year | month | sum_of_succes_amount | sum_of_fail_amount | sum_of_pending_amount |total
-----------------------------------------------------------------------------------------
2017 | January | 1350 | 750 | 0 | 2100
2017 | Febuary | 500 | 100 | 0 | 600
2017 | March | 500 | 0 | 0 | 500
2017 | April | 1200 | 200 | 600 | 2000
2017 | May | 0 | 0 | 600 | 600
What if I add The third table ? TBL_PENDING_ORDER
You can use the following solution using UNION ALL AND GROUP BY:
SELECT
YEAR(x.date),
MONTH(x.date),
SUM(CASE WHEN x.type = 'S' THEN amount ELSE 0 END) AS sum_of_succes_amount,
SUM(CASE WHEN x.type = 'F' THEN amount ELSE 0 END) AS sum_of_fail_amount,
SUM(amount) AS total
FROM (
SELECT id, date, amount, 'S' AS type FROM TBL_SUCCESS_ORDER
UNION ALL
SELECT id, date, amount, 'F' AS type FROM TBL_FAIL_ORDER
)x GROUP BY YEAR(x.date), MONTH(x.date)
You want to add the third table TBL_PENDING_ORDER?
SELECT
YEAR(x.date),
MONTH(x.date),
SUM(CASE WHEN x.type = 'S' THEN amount ELSE 0 END) AS sum_of_succes_amount,
SUM(CASE WHEN x.type = 'F' THEN amount ELSE 0 END) AS sum_of_fail_amount,
SUM(CASE WHEN x.type = 'P' THEN amount ELSE 0 END) AS sum_of_pending_amount,
SUM(amount) AS total
FROM (
SELECT id, date, amount, 'S' AS type FROM TBL_SUCCESS_ORDER
UNION ALL
SELECT id, date, amount, 'F' AS type FROM TBL_FAIL_ORDER
UNION ALL
SELECT id, date, amount, 'P' AS type FROM TBL_PENDING_ORDER
)x GROUP BY YEAR(x.date), MONTH(x.date)

Is it possible to aggregate rows like this in MySQL?

With the following table of car models,
+-------+----+-------+
| model | id | total |
+-------+----+-------+
| civic | 1 | 27 |
| civic | 3 | 11 |
| crv | 3 | 5 |
+-------+----+-------+
would it be possible to query in order to have this result?
+-------+-----+-----+-----+
| model | id1 | id2 | id3 |
+-------+-----+-----+-----+
| civic | 27 | 0 | 11 |
| crv | 0 | 0 | 5 |
+-------+-----+-----+-----+
This is a pivot query. One way to handle this in MySQL is conditional aggregation:
select model,
max(case when id = 1 then total else 0 end) as id1,
max(case when id = 2 then total else 0 end) as id2,
max(case when id = 3 then total else 0 end) as id3
from carmodels t
group by model;