sum 2 table got loop sql - mysql

SELECT brg_laku.id_brg, SUM( brg_laku.dibeli ) AS sold, SUM( stok_brg.stok ) AS stock
FROM brg_laku, stok_brg
WHERE stok_brg.id_brg = brg_laku.id_brg
GROUP BY stok_brg.id_brg, brg_laku.id_brg
This my sold table:
id_bl id_brg dibeli harga_laku tgl jam
10 BRG-000001 2 30000 2018-03-16 10:48:35
11 BRG-000001 1 35000 2018-03-16 10:48:38
12 BRG-000003 5 30000 2018-03-16 10:48:41
13 BRG-000003 4 35000 2018-03-16 10:47:13
This is the view using code above:
This my stok table:
How to make it sum correctly in SQL?

You should join the result sum
SELECT brg_laku.id_brg, t.sum_stock
, SUM( brg_laku.dibeli ) AS sold
FROM brg_laku
INNER JOIN (
SELECT
stok_brg.id_brg ,
SUM( stok_brg.stok ) sum_stok
FROM stok_brg
) t on t. id_brg = brg_laku.id_brg
group by brg_laku, t.sum_stock

Related

Cross tabulate data of products sold broken down by revenue and by product sold

Issues in getting the right frequency for the cross tabulated data. My expected output is something like this:
I tried replacing the COUNT statement with SUM statement
SUM(IF(product.product_id = 1, line_item.quantity, 0)) AS Soda,
SUM(IF(product.product_id = 2, line_item.quantity, 0)) AS Liquor,
SUM(IF(product.product_id = 3, line_item.quantity, 0)) AS Lemon,
SUM(IF(product.product_id = 4, line_item.quantity, 0)) AS Mango,
SUM(IF(product.product_id = 5, line_item.quantity, 0)) AS Inhaler,
SUM(1) AS Count
FROM line_item
JOIN product USING (product_id)
JOIN ( SELECT 0 lo, 500 hi UNION
SELECT 501 , 1000 UNION
SELECT 1001 , 1500 UNION
SELECT 1501 , 2000 UNION
SELECT 2001 , 2500 ) ranges ON (product.price * line_item.quantity) BETWEEN ranges.lo AND ranges.hi
GROUP BY ranges.lo, ranges.hi```
It is getting closer because it is distributing already the values in its ranges just that the values are not correct. I am expecting to see something like this:
[Expected Result][1]
[1]: https://i.stack.imgur.com/YuB92.png
After reviewing my code here is the answer:
SUM(product.product_id = 1) AS Soda,
SUM(product.product_id = 2) AS Liquor,
SUM(product.product_id = 3) AS Lemon,
SUM(product.product_id = 4) AS Mango,
SUM(product.product_id = 5) AS Inhaler,
SUM(1) AS Count
FROM line_item
JOIN product USING (product_id)
JOIN ( SELECT 0 lo, 500 hi UNION
SELECT 501 , 1000 UNION
SELECT 1001 , 1500 UNION
SELECT 1501 , 2000 UNION
SELECT 2001 , 2500 ) ranges ON product.price * line_item.quantity BETWEEN ranges.lo AND ranges.hi
GROUP BY ranges.lo, ranges.hi

Count Age With Distinctly in MySQL

I have a table like this
PersonID Gender Age CreatedDate
================================
1 M 32 10/09/2011
2 F 33 10/09/2011
2 F 33 10/11/2011
1 M 32 10/11/2011
3 F 33 10/11/2011
I want to find Gender Count By Age with group by created date,The age range will be 30-34 and getting person will be distinctly.
Desired output should like this:
Gender AgeRange CreatedDate CountResult
================================
M 30_34 10/09/2011 1
F 30_34 10/09/2011 1
F 30_34 10/11/2011 1
So I tried this but couldtn help:
SELECT t.Gender,'30_34' AS AgeRange,t.CreatedDate,
SUM(CASE WHEN t.Age BETWEEN 30 AND 34 THEN 1 ELSE 0 END) AS CountResult,
FROM (
SELECT DISTINCT PersonID,Gender,Age,CreatedDate
FROM MyTable
GROUP PersonID,Gender,Age,CreatedDate
HAVING COUNT(PersonID)=1
) t
What can I do for solution?
Thanks
If you are want the earliest created date per personid this might do
drop table if exists mytable;
create table mytable(PersonID int, Gender varchar(1),Age int, CreatedDate date);
insert into mytable values
(1 , 'M', 32 , '2011-09-10'),
(2 , 'F', 33 , '2011-09-10'),
(2 , 'F', 33 , '2011-11-10'),
(1 , 'M', 32 , '2011-11-10'),
(3 , 'F', 33 , '2011-11-10');
select mt.gender,
mt.createddate,
sum(case when mt.age between 32 and 34 then 1 else 0 end) as Age32to34
from mytable mt
where createddate = (select min(mt1.createddate) from mytable mt1 where mt1.personid = mt.personid)
group by gender,mt.createddate
How about:
SELECT
Gender
, '30_34' AS AgeRange
, CreatedDate
, COUNT(*) AS CountResult
FROM MyTable A
JOIN (
SELECT PersonID, MIN(CreatedDate) MinCreatedDate
FROM MyTable GROUP BY PersonID
) B ON B.PersonID = A.PersonID AND B.MinCreatedDate = A.CreatedDate
WHERE Age BETWEEN 30 AND 34
GROUP BY Gender, CreatedDate
ORDER BY CreatedDate, Gender DESC
You would appear to want:
SELECT t.Gender, '30_34' AS AgeRange, t.CreatedDate,
COUNT(DISTINCT t.PersonId) AS CountResult
FROM MyTable
WHERE t.Age BETWEEN 30 AND 34
GROUP BY t.Gender, t.CreatedDate;

Why MySQL full outer join returns nulls?

Why MySQL full outer join returns nulls?
Hi
I have the following data:
s_id,date,p_id,amount_sold
1, '2015-10-01', 1, 10
2, '2015-10-01', 2, 12
7, '2015-10-01', 1, 11
3, '2015-10-02', 1, 11
4, '2015-10-02', 2, 10
5, '2015-10-15', 1, 22
6, '2015-10-16', 2, 20
8, '2015-10-22', 3, 444
and i want my query to output something like this: (A = sum of amount_sold for p_id=1 for that date,B = sum of amount_sold for p_id=2 for that date)
date,A,B,Difference
'2015-10-01',21,12,9
'2015-10-02',11,10,1
'2015-10-15',22,0,22
'2015-10-01',0,20,-20
I tried with this query, but the order its returning is having NULLS and the output is wrong:
SELECT A.p_id,A.date,sum(A.amount_sold) A,B.Bs, (sum(A.amount_sold) - B.Bs) as difference FROM sales as A
LEFT JOIN (
SELECT SUM( amount_sold ) Bs,p_id,s_id, DATE
FROM sales
WHERE p_id =2
group by date
) as B ON A.s_id = B.s_id
where A.p_id=1 or B.p_id=2
group by A.date, A.p_id
UNION
SELECT A.p_id,A.date,sum(A.amount_sold) A,B.Bs, (sum(A.amount_sold) - B.Bs) as difference FROM sales as A
RIGHT JOIN (
SELECT SUM( amount_sold ) Bs,p_id,s_id, DATE
FROM sales
WHERE p_id =2
group by date
) as B ON A.s_id = B.s_id
where B.p_id=2
group by A.date, A.p_id
It returned:
p_id date A Bs difference
1 2015-10-01 21 NULL NULL
2 2015-10-01 12 12 0
1 2015-10-02 11 NULL NULL
2 2015-10-02 10 10 0
1 2015-10-15 22 NULL NULL
2 2015-10-16 20 20 0
What am i doing wrong here? and what is the correct way of doing it? any help would be appreciated.
A full join isn't needed. You can use conditional aggregation instead:
select
date,
sum(case when p_id = 1 then amount_sold else 0 end) a,
sum(case when p_id = 2 then amount_sold else 0 end) b,
sum(case when p_id = 1 then amount_sold else 0 end)
- sum(case when p_id = 2 then amount_sold else 0 end) difference
from sales
where p_id in (1,2)
group by date

MYSQL | Get two different records from single table

Ok. This is kind of complicated.. I have been trying to achieve it and got no where so far.
I have three tables.
leave_approval
leave_applications
ml_leave_type
Here is leave_approval Table
which is then linked to leave_application from leave_application_id
Now here comes the Tricky Question,
i want two records from table.
I want Total leaves taken by employee in year 2014
I want Total Leaves taken by employee in month november of 2014
so means need two columns with two different approaches yearly and monthly.
i have query so far.
SELECT
LA.employee_id,
DATEDIFF(
LA.approved_to,
LA.approved_from
) AS TotalLeavesTaken,
LAPP.`entitlement_id`,
LAPP.`ml_leave_type_id`,
LA.leave_application_id,
LA.approved_from AS LeaveFrom,
LA.approved_to AS LeaveTo
FROM
leave_approval LA
INNER JOIN leave_application LAPP
ON LAPP.application_id = LA.leave_application_id
WHERE YEAR(LA.approval_date) = 2014
AND LA.`employee_id` = 1
and here is the result i am getting for the query..
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
UPDATE
May i could not clearly explain my problem.
What i am trying to achieve is add two extra columns not remove the columns i have. i mean i am using most/All of the select fields i have
Plus i want the Total Leaves in Year 2014 in one column and Total Leaves in the month in different field for that given year.
so here is kind of example i want.>
ml_leave_type_id | Total Leaves Taken in Year (e-g 2014) | Total Leaves taken in Month (e-g November)
1 10 2
2 6 0
3 4 1
Would something like that do?
Total leaves for employee_id = 1, Year 2014
SELECT
LA.employee_id,
SUM(
DATEDIFF(
LA.approved_to,
LA.approved_from
)
) AS TotalLeavesTaken,
LAPP.`entitlement_id`,
LAPP.`ml_leave_type_id`,
LA.leave_application_id,
LA.approved_from AS LeaveFrom,
LA.approved_to AS LeaveTo
FROM
leave_approval LA
INNER JOIN leave_application LAPP
ON LAPP.application_id = LA.leave_application_id
WHERE YEAR(LA.approval_date) = 2014
AND LA.`employee_id` = 1
GROUP BY LA.`employee_id` = 1
Total leaves for employee_id = 1, Year = 2014 AND Month = 11
SELECT
LA.employee_id,
SUM(
DATEDIFF(
LA.approved_to,
LA.approved_from
)
) AS TotalLeavesTaken,
LAPP.`entitlement_id`,
LAPP.`ml_leave_type_id`,
LA.leave_application_id,
LA.approved_from AS LeaveFrom,
LA.approved_to AS LeaveTo
FROM
leave_approval LA
INNER JOIN leave_application LAPP
ON LAPP.application_id = LA.leave_application_id
WHERE YEAR(LA.approval_date) = 2014
AND MONTH(LA.approval_date) = 11
AND LA.`employee_id` = 1
GROUP BY LA.`employee_id` = 1
I do notice in your dataset however that there are some dates that are ovelapping. For example:
employee_id = 1 is on leave 2014/11/01 - 2014/11/06 AND 2014/11/05 - 2014/11/08. What's the deal with the dates 2014/11/05 and 2014/11/06. How will the system handle this scenario
Edit2: updated select statement after requirements clarified. The update consist of reorganizing with using a JOIN instead of UNION ALL
select a.*, b.*
from (
SELECT
LA.employee_id,
DATEDIFF(
LA.approved_to,
LA.approved_from
) AS TotalLeavesTaken,
LAPP.`entitlement_id`,
LAPP.`ml_leave_type_id`,
LA.leave_application_id,
LA.approved_from AS LeaveFrom,
LA.approved_to AS LeaveTo
FROM
leave_approval LA
INNER JOIN leave_application LAPP
ON LAPP.application_id = LA.leave_application_id
WHERE YEAR(LA.approval_date) = 2014
AND LA.`employee_id` = 1
) a
JOIN (
SELECT
LA.employee_id,
DATEDIFF(
LA.approved_to,
LA.approved_from
) AS TotalLeavesTaken,
LAPP.`entitlement_id`,
LAPP.`ml_leave_type_id`,
LA.leave_application_id,
LA.approved_from AS LeaveFrom,
LA.approved_to AS LeaveTo
FROM
leave_approval LA
INNER JOIN leave_application LAPP
ON LAPP.application_id = LA.leave_application_id
WHERE MONTHNAME(LA.approval_date) = 'November'
AND LA.`employee_id` = 1
) b
ON a.employee_id = b.employee_id

Getting SUM and JOIN to cooperate in a specific query

I'm stuck with a certain query, it seems to be simple but it seems I might have to split it in different ways to get it to accomplish what I want to do. I tried combining, recombining and I could use some guidance.
Here's a sample table, the output and expected output.
Shop_Table
shop_id | item_type | date
1 soaps 2000-01-01
2 food 2000-01-02
3 appliances 2000-01-03
4 electronics 2000-01-10
5 furniture 2000-01-13
6 misc. 2000-01-15
Instance_Table
instanceid| shop_id | firstname | lastname | number_of_items
11 3 jane doe 2
22 2 jane doe 3
33 1 jane doe 5
44 4 jane doe 6
55 6 jane doe 1
66 5 jane doe 2
The Query
SELECT
IF
(
Shop_Table.item_type
IN
(
'soaps',
'food'
),
'indexpensives',
Shop_Table.item_type
),
COALESCE(SUM(Person.number_of_items), 0) AS item_sum
FROM Shop_Table
INNER JOIN Instance_Table AS Instance
ON Instance.shop_id = Shop_Table.shop_id
AND Instance.firstname = 'jane'
AND Instance.lastname = 'doe'
AND Shop_Table.date BETWEEN DATE( '2000-01-01' ) AND DATE( '2000-01-03' )
GROUP BY Shop_Table.item_type
Which returns:
item_type | item_sum
indexpensives | 8
appliances | 2
Output
Which is great so far, and is where I'm stuck. What I really want is the following output:
Expected Output
item_type | item_sum
inexpensives | 8
appliances | 2
electronics | 0
furniture | 0
misc. | 0
I think it's pretty straight forward what I want to do. What's making it a little tough is that it has a little bit of everything.
Grouping and combining sum results (soaps and food into one result)
Returning 0 for the rest of the item types when the date is outside the specified range.
Update:
Turned out a little more complicated than I thought, but it's what I wanted. Thank you everyone for helping out.
SELECT
IF
(
Shop_Table.item_type
IN
(
'soaps',
'food'
),
'inexpensives',
Shop_Table.item_type
),
COALESCE(SUM(Person.number_of_items), 0) AS item_sum
FROM Shop_Table
LEFT OUTER JOIN Instance_Table AS Instance
ON Instance.shop_id = Shop_Table.shop_id
AND Instance.firstname = 'jane'
AND Instance.lastname = 'doe'
AND Shop_Table.date BETWEEN DATE( '2000-01-01' ) AND DATE( '2000-01-03' )
GROUP BY IF
(
Shop_Table.item_type
IN
(
'soaps',
'food'
),
'inexpensives',
Shop_Table.item_type
)
Change your query to this and you should get the totals you're looking for:
SELECT
IF
(
Shop_Table.item_type
IN
(
'soaps',
'food'
),
'indexpensives',
Shop_Table.item_type
),
SUM(Person.number_of_items) AS item_sum
FROM Shop_Table
LEFT OUTER JOIN Instance_Table AS Instance
ON Instance.shop_id = Shop_Table.shop_id
AND Instance.firstname = 'jane'
AND Instance.lastname = 'doe'
AND Shop_Table.date BETWEEN DATE( '2000-01-01' ) AND DATE( '2000-01-03' )
GROUP BY Shop_Table.item_type
Explanation
An outer join will select all rows from one table and matching rows from another. So, a LEFT OUTER JOIN will select all rows from the table on the left side of the join (Shop_Table in this case) and matching rows from the table on the right side of the join (Instance_Table in this case).
First of all replace your inner join with a left join and then make sure you coalesce the sum with a 0, like this:
SELECT
IF
(
Shop_Table.item_type
IN
(
'soaps',
'food'
),
'indexpensives',
Shop_Table.item_type
),
COALESCE(SUM(Person.number_of_items), 0) AS item_sum
FROM Shop_Table
LEFT JOIN Instance_Table AS Instance
ON Instance.shop_id = Shop_Table.shop_id
AND Instance.firstname = 'jane'
AND Instance.lastname = 'doe'
AND Shop_Table.date BETWEEN DATE( '2000-01-01' ) AND DATE( '2000-01-03' )
GROUP BY Shop_Table.item_type
Edit:
After the requirement changes, this should be the final query:
SELECT
IF
(
Shop_Table.item_type
IN
(
'soaps',
'food'
),
'inexpensives',
Shop_Table.item_type
) as FinalType,
COALESCE(SUM(Person.number_of_items), 0) AS item_sum
FROM Shop_Table
LEFT OUTER JOIN Instance_Table AS Instance
ON Instance.shop_id = Shop_Table.shop_id
AND Instance.firstname = 'jane'
AND Instance.lastname = 'doe'
AND Shop_Table.date BETWEEN DATE( '2000-01-01' ) AND DATE( '2000-01-03' )
GROUP BY FinalType