MYSQL: combine 2 count sql group by year - mysql

i have 2 Table with same structure, each of it i use the almost the same sql to select and SUM.
SQL1:
SELECT YEAR, SUM(GENERATION) AS generationA, SUM(TRANSMISSION) AS transmissionA
FROM tableA
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
GROUP BY YEAR
SQL2:
SELECT YEAR, SUM(GENERATION) AS generationB, SUM(TRANSMISSION) AS transmissionB
FROM tableB
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
GROUP BY YEAR
how to combine this 2 sql to group by its year?

Try this
select year, sum(generationA) as generationA, sum(transmissionA) as transmissionA from
(
SELECT YEAR, SUM(GENERATION) AS generationA, SUM(TRANSMISSION) AS transmissionA
FROM tableA
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
GROUP BY YEAR
union all
SELECT YEAR, SUM(GENERATION) AS generationB, SUM(TRANSMISSION) AS transmissionB
FROM tableB
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
GROUP BY YEAR
) as t
group by YEAR

You can use a join
SELECT
a.YEAR
, SUM(a.GENERATION) AS generationA
, SUM(a.TRANSMISSION) AS transmissionA
, SUM(b.GENERATION) AS generationB
, SUM(b.TRANSMISSION) AS transmissionB
FROM tableA as a
LEFT JOIN tableB as b on (a.YEAR = b.year
and a..POWER_PLANT_ID = b.POWER_PLANT_ID
and a.STATUS = b.STATUS
and a.transmission = b.transmission)
WHERE a.YEAR BETWEEN '2013' AND '2016'
AND a.POWER_PLANT_ID = 'ABC1'
AND a.STATUS = 'V'
AND a.transmission IS NOT NULL
GROUP BY a.YEAR

Try with the below script,if you wanted to sum up the the result sets by grouping with year.
SELECT YEAR,SUM(GENERATION) generation,SUM(TRANSMISSION)TRANSMISSION
FROM
(SELECT YEAR, GENERATION , TRANSMISSION
FROM tableA
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL
UNION ALL
SELECT YEAR, GENERATION, TRANSMISSION
FROM tableB
WHERE YEAR BETWEEN '2013' AND '2016'
AND POWER_PLANT_ID = 'ABC1'
AND STATUS = 'V'
AND transmission IS NOT NULL )AS t
GROUP BY YEAR

Related

Convert mysql to doctrine

I have the following MySQL query
select a.*, d.*, p.*, pow.* from appointment a
left join doctor d on d.id = a.doctor_id
left join patient p on p.id = a.patient_id
left join point_of_work pow on pow.id = a.point_of_work_id
where (doctor_id, patient_id, date) = (
select doctor_id, patient_id,
coalesce(
min(case when date > curdate() then date end),
max(case when date < curdate() then date end)
) date
from appointment
where (doctor_id, patient_id) = (a.doctor_id, a.patient_id)
)
and d.external_id = 1
And I am trying to convert it to DQL.
Right now I come to this version of DQL but it seems I'am doing something (or maybe more things:( wrong)
$expr = $this->getEntityManager()->getExpressionBuilder();
$queryBuilder = $this->createQueryBuilder('a')
->leftJoin(Doctor::class, 'd')
->leftJoin(Patient::class, 'p')
->leftJoin(PointOfWork::class, 'pow')
->where(
$expr->eq('doctorId, patient_id, date',
$this->createQueryBuilder('a')
->select(Appointment::class . ',
coalesce(
min(case when date > curdate() then date end),
max(case when date < curdate() then date end)
) date'
)
->where ('(doctorId, patientId) = (a.doctorId, a.patientId)')
)
)
->andWhere('d.externalId = :externalId')
->setParameter('externalId', $doctorExternalId)
->setMaxResults($limit)
->setFirstResult($offset);
What approaches do I need for the DQL conversion?

Join not summing CASE WHEN

What I'm looking to do is show my current performance for this month, compared with expected scheduled wins to come in and then display the total expected amount, by product type.
For clarity, I have two sub-products that I'm grouping under the same name.
My issue is that for my 'Charged' amount, it's keeping the two sub-products separate, where as the 'Scheduled' amount is working fine.
The table should look like:
Type | Charged | Scheduled | Expected
A 3 2 5
B 1 1 2
What's actually showing is:
Type | Charged | Scheduled | Expected
A 2 1 3
A 1 1 2
B 1 1 2
The code is as follows:
select
t2.product,
t1.Charged,
t2.Scheduled,
t1.charged + t2.scheduled as 'expected'
from(
select
case
when user_type = 'a1' then 'a'
when user_type = 'a2' then 'a'
else 'b'
end as 'Type',
SUM(charged) as 'Scheduled'
from
table
where
month(date) = month(now())
and
year(date) = year(now())
and status like 'scheduled'
group by 1
order by 2 desc) t2 join
(select
case
when user_type = 'a1' then 'a'
when user_type = 'a2' then 'a'
else 'b'
end as 'Type',
sum(charged) as 'Charged'
FROM table
WHERE (status = 'Complete'
AND str_to_date(concat(date_format(date, '%Y-%m'), '-01'), '%Y-%m-%d') = str_to_date(concat(date_format(now(), '%Y-%m'), '-01'), '%Y-%m-%d'))
GROUP BY user_type
ORDER BY user_type ASC) as t1 on t1.type = t2.type
I appreciate I might not be explaining this incredibly well (and that my code is probably quite clunky - I'm still fairly new!) so any help/direction would be appreciated.
Thanks!
Just some suggestion
you have a column product in main select but you have type in subquery and not product
you should not use sigle quote around column name
ad you have group by user_type but you need group by type for charged
select
t2.type,
t1.Charged,
t2.Scheduled,
t1.charged + t2.scheduled as 'expected'
from(
select
case
when user_type = 'a1' then 'a'
when user_type = 'a2' then 'a'
else 'b'
end as Type,
SUM(charged) as Scheduled
from
table
where
month(date) = month(now())
and
year(date) = year(now())
and status like 'scheduled'
group by 1
order by 2 desc) t2 join
(select
case
when user_type = 'a1' then 'a'
when user_type = 'a2' then 'a'
else 'b'
end as Type,
sum(charged) as Charged
FROM table
WHERE (status = 'Complete'
AND str_to_date(concat(date_format(date, '%Y-%m'), '-01'), '%Y-%m-%d') = str_to_date(concat(date_format(now(), '%Y-%m'), '-01'), '%Y-%m-%d'))
GROUP BY Type
ORDER BY Type ASC) as t1 on t1.type = t2.type

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')

Return the original value if there is a null in the computation

I'm having trouble with my query in getting only the original value if its computing a null value from another type. I'm computing those original values according to type 5 minus to typeid 10.
Please take note that my data structure and my data types are all over the place and will be hard to read for new users. In order to determine the value, you have to focus on type and typeid.
The type that I get in getting the original value for the discounts is 5
Here are the query and original values:
Query:
select a.ID as `ID`, a.DOB as `DATE`, a.AMOUNT as `TOTAL`, (SELECT
coalesce(sum(case when gndsale.type= "5" then gndsale.amount end), 0) from
gndsale where gndsale.ID = b.ID and gndsale.DOB = a.DOB having
sum(gndsale.type = "5") > 0 ) as `DISCOUNTS` FROM gndsale a
INNER JOIN emp b ON a.ID = b.ID
WHERE a.type = "22" and STR_TO_DATE(a.DOB, '%m/%d/%Y') BETWEEN '2017-05-01'
AND '2017-05-31' GROUP BY TOTAL order by STR_TO_DATE(a.DOB, '%m/%d/%Y')
I have a typeid of 10 that will determine another discount which is senior
Here are the query and the values of senior
Query:
select a.ID as `ID`, a.DOB as `DATE`, a.AMOUNT as `TOTAL`, (SELECT
coalesce(sum(case when gndsale.typeid= "10" then gndsale.amount end), 0) from
gndsale where gndsale.ID= b.ID and gndsale.DOB = a.DOB having
sum(gndsale.typeid = "10") > 0 ) as `DISCOUNTS` FROM gndsale a
INNER JOIN emp b ON a.ID= b.ID
WHERE a.type = "22" and STR_TO_DATE(a.DOB, '%m/%d/%Y') BETWEEN '2017-05-01'
AND '2017-05-31' GROUP BY TOTAL order by STR_TO_DATE(a.DOB, '%m/%d/%Y')
I have a null value with my Senior Discount.
What I want to do is I want to minus the original Discounts value and the Senior Discounts value which means I have to minus the value that has a type = 5 and a typeid = 10 . Fortunately, I was able to compute and I got my result
HERE IS THE PROBLEM I have a null value on my expected result. The problem is because its computing a null value from the Senior result what I want is that the null value should return only the Original Discount Value if its computing null values.
Here's my query:
select a.ID as `ID`, a.DOB as `DATE`, a.AMOUNT as `TOTAL`, (SELECT
coalesce(sum(case when gndsale.type= "5" then gndsale.amount end), 0) -
coalesce(sum(case when gndsale.TYPEID= "10" then gndsale.amount end), 0) END
from gndsale where gndsale.ID= b.ID and gndsale.DOB = a.DOB having
sum(gndsale.type = "5") > 0 and sum(gndsale.TYPEID= "10") > 0 ) as `OTHER
DISCOUNT` FROM gndsale a INNER JOIN emp b ON a.ID= b.ID WHERE a.type
= "22" and STR_TO_DATE(a.DOB, '%m/%d/%Y') BETWEEN '2017-05-01' AND '2017-05-
31' GROUP BY TOTAL order by STR_TO_DATE(a.DOB, '%m/%d/%Y')
Note: THEY ARE BASED ON THE DATES and I can't post pictures yet.. My current result I'm having is on the Other Discount.

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