Group data monthly and city - mysql

I have written a query to get this data, but this data is based from today to 22-01-2016.
I want to write it in a way that it should show the values for January, then February as I want to see how much TotalCredit is being increased monthly.
Please view the data as image

SELECT
City,
Sum(Violations) AS TotalViolations,
SUM(USDSpent) AS 'TotalCredit(USD)'
FROM
(
SELECT
city. NAME AS City,
count(user_credit.booking_id) AS Violations,
Round(SUM(amount / usd_rate_to), 1) AS USDSpent,
user_credit.creation_date AS Date
FROM
user_credit
JOIN booking ON user_credit.booking_id = booking.id
JOIN booking_detail ON booking.id = booking_detail.booking_id
JOIN drivers ON booking_detail.assigned_driver_id = drivers.id
JOIN limo_company ON drivers.limo_company_id = limo_company.id
JOIN city ON limo_company.city_id = city.id
JOIN customer_car_type cct ON booking.customer_car_type_id = cct.id
JOIN service_area ON cct.service_area_id = service_area.id
JOIN currency_exchange ON user_credit.base_currency_exchange_id = currency_exchange.id
WHERE
user_credit.creation_date BETWEEN SUBDATE(CURDATE(), INTERVAL 1 MONTH)
AND NOW()
GROUP BY
Date
) AS tableA
GROUP BY City,month(creation_date)

Related

How can I GROUP BY SELECT subquery aggregates?

first time on here, hoping for help. (MySQL) I tried to use subqueries in a SELECT statement but when I GROUP BY, the single aggregate value outputs of the subqueries just produce the one same value for all rows in the table. This implies they are not GROUPED, right? How close am I to getting this right? Thanks
SELECT
c.name, ca.name, DATE_FORMAT(sp.created,'%Y%m') AS yr_month,
ss.signup_source, count(sp.seller_profile_id) AS No_seller_profiles,
(SELECT SUM(seller_invoice.gbp_value)/100
FROM seller_invoice JOIN seller_profile
ON seller_invoice.seller_profile_id = seller_profile.seller_profile_id
WHERE seller_invoice.created BETWEEN seller_profile.created AND ADDDATE(seller_profile.created, INTERVAL 30 DAY)),
(SELECT count(project_response.project_response_id)
FROM project_response JOIN seller_profile
ON project_response.seller_profile_id = seller_profile.seller_profile_id
WHERE project_response.created BETWEEN seller_profile.created AND ADDDATE(seller_profile.created, INTERVAL 30 DAY) AND project_response.is_visible_to_seller = 1)
FROM seller_profile AS sp
JOIN country AS c ON sp.country_id = c.country_id
JOIN seller_category AS sc ON sp.seller_profile_id = sc.seller_profile_id
JOIN category AS ca ON sc.category_id = ca.category_id
JOIN seller_signup_source AS ss ON sp.seller_profile_id = ss.seller_profile_id
WHERE sp.created BETWEEN '2018-11-01' AND '2018-12-31'
GROUP BY 1,2,3,4;

Return single record from another table with multiple records per transactionDate

How can I create a query that will return the latest Soa LoanableAmount based on the LoanApplicationDate.
Ex:
For LoanID = 1, I want to get the Soa record with SoaID = 2 since this is the latest loanable amount for this LoanApplicationDate - 2017-07-01.
So far this is what I have accomplished:
select *
from Loan L
join Soa S
ON S.EmployeeID = L.EmployeeID
where S.TransactionDate <= L.LoanApplicationDate
To illustrate what I want to accomplish, please see screenshot below.
https://www.db-fiddle.com/f/3PBossUJLYQTQZJfZymiph/0
I think you want a join and then to filter to get the most recent date:
select l.*, s.*
from Loan l join
Soa s
on s.employeeid = l.employeeid
where s.TransactionDate <= (select max(s2.TransactionDate)
from Soa s2
where s2.employeeid = l.employeeid and
s2.TransactionDate <= l.LoanApplicationDate
);
I think you need to set the condition on the join:
select
L.LoanID,
L.EmployeeID,
L.LoanAmount,
L.LoanApplicationDate,
S.LoanableAmount,
S.TransactionDate
from Loan L join Soa S
ON S.EmployeeID = L.EmployeeID and
S.TransactionDate = (select max(TransactionDate) from Soa where TransactionDate <= L.LoanApplicationDate)
See the demo
SQL DEMO
select *
from Loan L
join Soa S
ON S.EmployeeID = L.EmployeeID
and S.TransactionDate =
(select max(S2.TransactionDate)
from Soa S2
where S2.TransactionDate <= L.LoanApplicationDate
and S2.`EmployeeID` = L.`EmployeeID`
)
The below query will give you all employee ids with loanable amount withdrawn on latest date
Select employee_id,
LoanableAmount
transactionDate from table
having
transactionDate=max(transactionDate)
group by employee_id
You need to run a subquery for each row:
select q.*, S.LoanableAmount, S.TransactionDate from
(select
L.*
,(select SoaID from Soa x where x.EmployeeID = L.EmployeeID and x.TransactionDate <= L.LoanApplicationDate order by TransactionDate DESC limit 1) as SoaID
from Loan L) q
join Soa S on S.SoaID = q.SoaID
Line 4 will give you the SoaID of the row in the Soa table that has the newest date that is less than or equal to the Application Date, then with that ID you just join and show the rest of the fields.

how to get last record of table in sql

I have three entries in the attendance table.But I need to print the last entry of the id from the attendance table.I calculated total duration in separate query and printing list in separate query.Anyone please help me to resolve this.
query to print total duration:
select SEC_TO_TIME(sum(case when a.endtime IS NULL
then time_to_sec(TIMEDIFF(NOW(),a.starttime))
else time_to_sec(a.duration)
end)
) as duration
from attendance a
left join staff s on a.staffid=s.id
left join company c on a.companyid=c.companyid
where DATE_FORMAT(a.createdon, '%Y/%m/%d') = DATE_FORMAT('2017-04-04', '%Y/%m/%d') and
(a.employeecode ='A101' OR 'A101'='') and
(a.companyid=0 OR 0=0)
group by a.employeecode,a.companyid order by a.id desc
Query to print the details:
select a.id,
a.starttime,
a.endtime,
a.startlocation,
a.endlocation,
a.duration,
a.companyid,
a.employeecode,
a.staffid,
a.createdon,
a.createdby,
a.lastmodifiedon,
a.reason,
a.comments,
s.name as staffName,
c.company_name as companyName
from attendance a
left joinstaff s on a.staffid=s.id
left join company c on a.companyid=c.companyid
where DATE_FORMAT(a.created_on, '%Y/%m/%d') = DATE_FORMAT('2017-04-04', '%Y/%m/%d') and
(a.employeecode ='A101' OR 'A101'='') and
(a.company_id=0 OR 0=0)
group by a.employeecode,a.companyid order by a.id desc
I got output by setting the endtime as null.
`select SEC_TO_TIME(sum(case when a.endtime IS NULL then time_to_sec(TIMEDIFF(NOW(),a.starttime)) else time_to_sec(a.duration) end))
from attendance a left join staff s on a.staffid=s.id
left join company c on a.companyid=c.companyid
where DATE_FORMAT(a.createdon, '%Y/%m/%d') = DATE_FORMAT('', '%Y/%m/%d') and
(a.employeecode ='' OR ''='') and
(a.companyid=0 OR 0=0)
group by a.employeecode,a.companyid order by a.id desc`

GROUP BY from inner SELECT suquery is ignored in column sum

I have following query
SELECT YEAR(T.date), MONTH(T.date), T.production, T.lineID, SUM(rework + scrap)
FROM
(SELECT MAX(positionID), date, production, lineID
FROM productionPerPosition
WHERE lineID = 2
AND date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY date) AS T
INNER JOIN linePosition lp ON lp.lineID = T.lineID
INNER JOIN fttErrorType fet ON fet.positionID = lp.positionID
INNER JOIN fttData fd ON fd.errorID = fet.errorID
AND fd.date = T.date
GROUP BY YEAR(T.date), MONTH(T.date)
which gives this result
Now, I would like to group these results by year and month to get sum of production and sum of last column. I've tried this query
SELECT YEAR(T.date), MONTH(T.date), SUM(T.production), T.lineID, SUM(rework + scrap)
FROM
(SELECT MAX(positionID), date, production, lineID
FROM productionPerPosition
WHERE lineID = 2
AND date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY date) AS T
INNER JOIN linePosition lp ON lp.lineID = T.lineID
INNER JOIN fttErrorType fet ON fet.positionID = lp.positionID
INNER JOIN fttData fd ON fd.errorID = fet.errorID
AND fd.date = T.date
GROUP BY YEAR(T.date), MONTH(T.date)
Which gives me
Here production sum is wrong! It seems that GROUP BY from 7th line in first query is ignored.
Any idea how could I get needed result?
Edit: In inner SELECT I have separate production for several different positions (positionID) but I'm using only production from position that has highest positionID
Group has missing grouping columns that why it is resulting in some unexpected result
SELECT YEAR(T.date), MONTH(T.date), SUM(T.production), T.lineID, SUM(rework + scrap)
FROM
(SELECT MAX(positionID), date, production, lineID
FROM productionPerPosition
WHERE lineID = 2
AND date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY date, production, lineID) AS T
INNER JOIN linePosition lp ON lp.lineID = T.lineID
INNER JOIN fttErrorType fet ON fet.positionID = lp.positionID
INNER JOIN fttData fd ON fd.errorID = fet.errorID
AND fd.date = T.date
GROUP BY YEAR(T.date), MONTH(T.date), T.lineID
Has explained in e4c5 comment, you have to add all the unaggregated fields to your GROUP BY. I made it in the inner SELECT and in the main SELECT:
SELECT YEAR(T.date), MONTH(T.date), SUM(T.production), T.lineID, SUM(rework + scrap)
FROM
(SELECT MAX(positionID), date, production, lineID
FROM productionPerPosition
WHERE lineID = 2
AND date BETWEEN '2017-01-01' AND '2017-01-31'
GROUP BY date, production, lineID) AS T
INNER JOIN linePosition lp ON lp.lineID = T.lineID
INNER JOIN fttErrorType fet ON fet.positionID = lp.positionID
INNER JOIN fttData fd ON fd.errorID = fet.errorID
AND fd.date = T.date
GROUP BY YEAR(T.date), MONTH(T.date), T.lineID

MySQL getting sum of tables with the same id

I have four tables person,loan,ca,payments
I would like to get the sum of all payments amounts and cash advance amounts which has the same ID as the loan joined with a person from a specific date.
Here is my code, but the sum is calculated incorrectly:
SELECT pd.*,
l.total_loan_amount,
sum(c.ca_total_amount) AS ctot,
sum(p.payment_amount)
FROM personal_data pd
LEFT JOIN loans l
ON pd.id_personal_data = l.id_personal_data
LEFT JOIN ca c
ON l.id_loan = c.id_loan
LEFT JOIN payments p
ON l.id_loan = p.id_loan
WHERE l.loan_date = curDate()
AND (
c.ca_date = curDate()
OR c.ca_date IS NULL
)
AND (
p.payment_date = curDate()
OR p.payment_date IS NULL
)
GROUP BY pd.id_personal_data
Doing that may sometimes retrieve invalid results because id may or may not sometimes be present on other table.
Try using a subquery for each column you want to retrieve.
SELECT pd.*,
l.total_loan_amount,
c.totalCA,
p.totalPayment
FROM personal_data pd
LEFT JOIN loans l
ON pd.id_personal_data = l.id_personal_data
LEFT JOIN
(
SELECT id_loan, SUM(ca_total_amount) totalCA
FROM ca
-- WHERE DATE(ca_date) = DATE(CURDATE()) OR
-- ca_date IS NULL
GROUP BY id_loan
) c ON l.id_loan = c.id_loan
LEFT JOIN
(
SELECT id_loan, SUM(payment_amount) totalPayment
FROM payments
-- WHERE DATE(payment_date) = DATE(CURDATE()) OR
-- payment_date IS NULL
GROUP BY id_loan
) p ON l.id_loan = p.id_loan
WHERE DATE(l.loan_date) = DATE(curDate())
I think dates on every payment and cash advance are irrelevant because you are looking for its totals based on the date of loan