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
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
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?
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
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
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