mysql get difference of two sum on the same table - mysql

how can i get the result in just one query instead of this one:
SELECT SUM(`quantity`) as type0 FROM `fruits_delivery`
WHERE `fid`='1001' AND `type`=0;
result_1 = type0 ;
SELECT SUM(`quantity`) as type1 FROM `fruits_delivery`
WHERE `fid`='1001' AND `type`=1;
result_2 = type1 ;
final_result = result_1 - result_2;

You should use this
SELECT sum(IF(`type`=0, `quantity`, 0))-sum(IF(`type`=1, `quantity`, 0))
AS `final_result`
FROM `fruits_delivery`
WHERE `fid` = '1001'
sqlfiddle
Old Answer
SELECT T1.result - T2.result AS `final_result`
FROM (SELECT Sum(`quantity`) AS result,
`fid`
FROM `fruits_delivery`
WHERE `fid` = '1001'
AND `type` = 0
LIMIT 1) AS T1
JOIN (SELECT Sum(`quantity`) AS result,
`fid`
FROM `fruits_delivery`
WHERE `fid` = '1001'
AND `type` = 1
LIMIT 1) AS T2
ON ( T1.fid = T2.fid )
SQLFiddle

Alternatively, you can also do it using CASE
SELECT SUM(CASE WHEN type = 0 THEN quantity ELSE 0 END) -
SUM(CASE WHEN type = 1 THEN quantity ELSE 0 END)
AS final_result
FROM fruits_delivery
WHERE fid = '1001'
SQLFiddle Demo

Related

Triple SELECT from the same table MySQL

I'd like to group all these queries within the same table:
SELECT orgname, COUNT(username)
FROM `user`
GROUP BY orgname;
SELECT COUNT(username) AS 'users_with_2FA'
FROM `user`
WHERE two_fa_enabled = 1
GROUP BY orgname;
SELECT COUNT(username) AS 'users_pending_2FA'
FROM `user`
WHERE two_fa_required_date IS NOT NULL AND two_fa_enabled IS NULL
GROUP BY orgname;
Please try this using CASE as suggested by #jarlh
SELECT orgname, COUNT(username) AS 'users_all'
, SUM((CASE WHEN two_fa_enabled = 1 THEN 1 ELSE 0 END)) AS 'users_with_2FA'
, SUM((CASE WHEN (two_fa_required_date IS NOT NULL AND two_fa_enabled IS NULL) THEN 1 ELSE 0 END)) AS 'users_pending_2FA'
FROM `user`
GROUP BY orgname;

Grouping different column into one row

How to make one row in different rows and column
SELECT
internal_id, store_id, user_id, shift_info,
DATE(log_datetime) dates,
(case when log_action = '0' then TIME(log_datetime) end) as time_in,
(case when log_action = '0' then CONCAT(log_lat, ",", log_lng) end) as loc_in,
(case when log_action = '1' then TIME(log_datetime) end) as time_out,
(case when log_action = '1' then CONCAT(log_lat, ",", log_lng) end) as loc_out
FROM
attendance_store_user
WHERE
user_id = "A4CBD64F-D21C-5612-CCF5-497892B62E76"
i want result like this :
You could try using a join of the same table filter for null time_out and time_in
select a.dates, a.store_id, a,time_in, b.time_out
FROM attendance_store_user a
INNER JOIN attendance_store_user b on a.dates = b.dates
and a.user_id = b.user_id
and a.time_out is null
and b.time_in is null
WHERE a.user_id = "A4CBD64F-D21C-5612-CCF5-497892B62E76"

Combining all data with a unique ID - MySQL

I have this data that I got from my current query.
What I want to do is combine and make it a single row where the type is Senior, the cashamount and Tenderamount are the same as well.
This is my desired result:
I'm getting my data from this table:
Here's my query:
SELECT a.DATE as `DATE`, a.employee as `EMPLOYEE`, a.TYPEID, a.NAME as
`NAME`, (select (case when a.typeid = 1 then a.amount else NULL end)) as
`CASHAMOUNT`,
(select (case when a.typeid <> 1 then a.amount else NULL end)) as
`TENDERAMOUNT`, (select gndtndr.IDENT from gndtndr where gndtndr.TYPE = 12
and `gndtndr`.`CHECK`= a.CHECK and gndtndr.DATE = a.DATE) as `ID`,
from gndtndr a
where STR_TO_DATE(a.DATE, '%m/%d/%Y') BETWEEN '20170901' AND '20170901'
order by STR_TO_DATE(a.DATE, '%m/%d/%Y')
My MySQL is a bit rusty, but give this a try!
SELECT a.Date, a.Employee, a.Name, a.ID, SUM(b.Amount) AS CashAmount,
SUM(c.Amount) AS TenderAmount FROM
(SELECT DISTINCT Date, Employee, Name, ID FROM gndtndr WHERE Type = 12) AS a
LEFT JOIN gndtndr AS b
ON a.ID = b.ID AND b.TypeID = 1
LEFT JOIN gndtdr AS c
ON a.ID = c.ID and c.TypeID <> 1
GROUP BY a.Date, a.Employee, a.Name, a.ID
I've figured it out :) I just have to define the type conditions in my where clause where the type is 1(for cash).
SELECT a.DATE as `DATE`, a.employee as `EMPLOYEE`, a.TYPEID, a.NAME as
`NAME`, (select sum(gndtndr.amount) from gndtndr where gndtndr.typeid = 1
and gndtndr.`CHECK` = a.`CHECK` and gndtndr.DATE = a.DATE) as `CASHAMOUNT`,
(select (case when a.typeid <> 1 then a.amount else NULL end)) as
`TENDERAMOUNT`, (select gndtndr.IDENT from gndtndr where gndtndr.TYPE = 12
and `gndtndr`.`CHECK`= a.CHECK and gndtndr.DATE = a.DATE) as `ID` from
gndtndr a
where a.TYPEID <> 1 and STR_TO_DATE(a.DATE, '%m/%d/%Y') BETWEEN '20170901'
AND '20170901' order by STR_TO_DATE(a.DATE, '%m/%d/%Y')

MySQL - conditional select in group

I have a simple table with several rows and I would like to group them by id_room and select value only when condition is true. Problem is that condition is always false even there is a row with right date column year_month.
Here is schema:
CREATE TABLE tbl_account_room (
`id` int,
`year_month` date,
`value` int,
`id_room` int
);
INSERT INTO tbl_account_room
(`id`, `year_month`, `value`, `id_room`)
VALUES
(1, '2016-08-01', 1, 300),
(2, '2016-09-01', 2, 300),
(3, '2016-10-01', 3, 300);
and here query:
SELECT
(case when '2016-10-01' = ar.year_month then ar.value else 0 end) as total
FROM tbl_account_room AS ar
WHERE ar.year_month >= "2016-08-01"
AND ar.year_month <= "2016-11-01"
and ar.id_room = '300'
GROUP BY ar.id_room
LIMIT 10
Here is SQL Fiddle
In column total I'm getting 0 and I would like to get value 3 because year_month is 2016-10-01. Why this happens?
You certainly don't need that CASE condition and include that condition in your WHERE clause rather like
SELECT
ar.value as total,
GROUP_CONCAT(ar.year_month)
FROM tbl_account_room AS ar
WHERE ar.year_month = '2016-10-01'
GROUP BY ar.id_room;
Not sure why you want the result like that, here you can use self join to do that:
SELECT
MAX(t1.value) as total,
GROUP_CONCAT(ar.year_month)
FROM tbl_account_room AS ar
LEFT JOIN tbl_account_room AS t1
ON ar.id_room = t1.id_room
AND ar.year_month = t1.year_month
AND t1.year_month = '2016-10-01'
WHERE ar.year_month >= "2016-08-01"
AND ar.year_month <= "2016-11-01"
and ar.id_room = '300'
GROUP BY ar.id_room
LIMIT 10;
and here is SQLFiddle Demo.

How to perform multiple calculations with in a single query

I have a situation where in i have to get the data from an Year Ago , Previous Month and Current Month. What is the best way to achieve this ?
I have a table which contains the year,month and data in it. In the below query have added a filter
c.ReportMonth = DATENAME(month, #12MonthsAgo) and c.ReportYear = Year(#12MonthsAgo)
This is for an year ago. In the same way if i have to get the previous month and current month, can i do that with in the same query by setting the filters ? how do we do that ?
Is there a better way other than i end up writing 3 select queries and then putting the select to a tmp table and later merging the tables ?
create table #TPTABLE
(
KPIName varchar(150)
,MetricName Varchar(200)
,MetricId INT
,DataSource varchar(50)
,[AnYearAgo] Float
,[PreviousMonth] float
,[CurrentMonth] float
);
insert into #TPTABLE
(KPIName,MetricName,MetricId,DataSource,[AnYearAgo])
SELECT
p.KPIName
,p.MetricName
,p.MetricId
,p.DataSource
,c.Value as [AnYearAgo]
FROM [IntegratedCare].[report].[KPIMetricDetails] p
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c
ON p.[MetricId] = c.MetricId
WHERE c.ReportMonth = DATENAME(month, #12MonthsAgo) and c.ReportYear = Year(#12MonthsAgo)
ORDER BY KPI_Id ASC, [MetricId] ASC
SELECT
p.KPIName
,p.MetricName
,p.MetricId
,p.DataSource
,c.Value
,c2.Value
,c3.Value
FROM [IntegratedCare].[report].[KPIMetricDetails] p
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c
ON p.[MetricId] = c.MetricId
AND c.[CommissionerCode] = COALESCE(NULLIF(#Commissioner, ''), c.[CommissionerCode])
ANd ReportMonth = DATENAME(month, #12MonthsAgo) and c.ReportYear = Year(#12MonthsAgo)
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c2
ON p.[MetricId] = c2.MetricId
AND c2.[CommissionerCode] = COALESCE(NULLIF(#Commissioner, ''), c2.[CommissionerCode])
ANd c2.ReportMonth = DATENAME(month, #PreviousMonth) and c2.ReportYear = Year(#PreviousMonth)
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c3
ON p.[MetricId] = c3.MetricId
AND c3.[CommissionerCode] = COALESCE(NULLIF(#Commissioner, ''), c3.[CommissionerCode])
ANd c3.ReportMonth = DATENAME(month, #PreviousMonth) and c3.ReportYear = Year(#PreviousMonth)
ORDER BY p.KPI_Id ASC, p.[MetricId] ASC
I think what you need is this:
insert into #TPTABLE
(KPIName,MetricName,MetricId,DataSource,[AnYearAgo])
SELECT
KPIName
,MetricName
,MetricId
,DataSource
,[AnYearAgo]
,[PreviousMonth]
,[CurrentMonth]
FROM (
SELECT
KPIName
,MetricName
,MetricId
,DataSource
,KPI_Id
,sum(case when c.ReportMonth = DATENAME(month, #12MonthsAgo) and c.ReportYear = Year(#12MonthsAgo) then c.Value else 0 end) as [AnYearAgo]
,sum(case when c.ReportMonth = DATENAME(month, #PreviousMonth) and c.ReportYear = Year(#PreviousMonth) then c.Value else 0 end) as [PreviousMonth]
,sum(case when c.ReportMonth = DATENAME(month, #CurrentMonth) and c.ReportYear = Year(#CurrentMonth) then c.Value else 0 end) as [CurrentMonth]
FROM [IntegratedCare].[report].[KPIMetricDetails] p
LEFT JOIN [IntegratedCare].[report].[KPIMectricValues] c
ON p.[MetricId] = c.MetricId
GROUP BY KPIName, MetricName, MetricId, DataSource, KPI_Id
ORDER BY KPI_Id ASC, [MetricId] ASC