MySQL getting sum of tables with the same id - mysql

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

Related

Is there a method of counting an attribute that is in a GROUP BY clause?

I need have created a select statement to list out all the customers that have been to multiple merchants below.
I want to create another statement to display how many of those customers have been to each merchant.
What is the optimal method of approaching this problem?
Lists out all customers that have been to multiple merchants.
WITH valentinesDayMerchant AS (
SELECT m.MerchantId, m.MerchantGroupId, m.WebsiteName
FROM Merchant m
INNER JOIN OpeningHours oh ON m.MerchantId = oh.MerchantId AND oh.DayOfWeek = 'TUE'
LEFT JOIN devices.DeviceConnectionState AS dcs ON dcs.MerchantId = oh.MerchantId
WHERE MerchantStatus = '-' AND (m.PrinterType IN ('V','O') OR dcs.State = 1 OR dcs.StateTransitionDateTime > '2023-01-23')
)
SELECT DISTINCT ul.UserLoginId, ul.FullName, ul.EmailAddress, ul.Mobile
FROM dbo.UserLogin AS ul
INNER JOIN dbo.Patron AS p ON p.UserLoginId = ul.UserLoginId
INNER JOIN valentinesDayMerchant AS m ON (m.MerchantId = ul.ReferringMerchantId OR m.MerchantId IN (SELECT pml.MerchantId FROM dbo.PatronMerchantLink AS pml WHERE pml.PatronId = p.PatronId AND ISNULL(pml.IsBanned, 0) = 0))
LEFT JOIN (
SELECT mg.MerchantGroupId, mg.MerchantGroupName, groupHost.HostName [GroupHostName]
FROM dbo.MerchantGroup AS mg
INNER JOIN dbo.Merchant AS parent ON parent.MerchantId = mg.ParentMerchantId
INNER JOIN dbo.HttpHostName AS groupHost ON groupHost.MerchantID = parent.MerchantId AND groupHost.Priority = 0
) mGroup ON mGroup.MerchantGroupId = m.MerchantGroupId
LEFT JOIN (
SELECT po.PatronId, MAX(po.OrderDateTime) [LastOrder]
FROM dbo.PatronsOrder AS po
GROUP BY po.PatronId
) orders ON orders.PatronId = p.PatronId
INNER JOIN dbo.HttpHostName AS hhn ON hhn.MerchantID = m.MerchantId AND hhn.Priority = 1
WHERE ul.UserLoginId NOT IN (1,2,100,372) AND ul.UserStatus <> 'D' AND (
ISNULL(orders.LastOrder, '2000-01-01') > '2020-01-01' OR ul.RegistrationDate > '2022-01-01'
)
GROUP BY ul.UserLoginId, ul.FullName, ul.EmailAddress, ul.Mobile
HAVING COUNT(m.MerchantId) > 1
Methods I have tried include adding the merchant name to a group by and displaying the count of the customers, however this does not work as I cannot have anything related to the Merchant in the GROUP BY, or I wouldn't be able to use HAVING clause to identify the customers that have been to multiple merchants. I have also tried selecting all the merchants and counting the distinct customers which doesn't work as it takes into account all the customers, not specifically the customers that have been to multiple merchants only.

MySQL stuck on this query

Is there is something wrong with this query?
It was tested and working (quite fast) and one day just stopped - never ends (query is wrong or something with MySQL?).
I have to update table turnover taking values from sales_history. Because key is vat_no, I have to join table clients to read customer vat_no from that table.
TURNOVER tbl
vat_no
billing_month
turnover
SALES_HISTORY tbl
customer_number
sales_amount
...
CLIENTS tbl
customer_number
vat_no
...
UPDATE turnover t
INNER JOIN (
SELECT c.vat_no, sales_history.billing_month, sales_history.customer_number, sum(sales_amount) as turnover
FROM sales_history
LEFT JOIN clients c
ON sales_history.customer_number = c.customer_number
WHERE sales_history.billing_month = '2018-01-01'
GROUP BY c.vat_no
) sales_history
ON sales_history.vat_no = t.vat_no
SET t.turnover = turnover
WHERE t.billing_month = '2018-01-01'
Why left join in the subquery if you need the result as key for update ?
i think you sould use INNER JOIN
UPDATE turnover t
INNER JOIN (
SELECT c.vat_no, sum(sales_amount) as turnover
FROM sales_history
INNER JOIN clients c ON sales_history.customer_number = c.customer_number
WHERE sales_history.billing_month = '2018-01-01'
and c.vat_no is not null
GROUP BY c.vat_no
) s ON s.vat_no = t.vat_no
SET t.turnover = turnover
WHERE t.billing_month = '2018-01-01'
and for performance be sure you have a composite index on
table turnover columns (billing_month , vat_no)
and on
table clients on column customer_number

mysql - Adding median to this query

One product ID has many prices. I'm trying to find the prices that are likely incorrect by comparing each price with the median price of the product. Currently I have min and max in the output and would like to add a single column for each product's median price. I have tried avg() but this returns: Invalid input syntax for type numeric. Any ideas?
select
distinct dp.product_id,
pc.warehouse_id as retailer_id,
pc.code,
dp.product_name,
dp.product_brand_name,
dp.product_size,
dp.product_unit_count,
pd.product_name as retailer_name,
pd.brand_name as retailer_brand_name,
pd.size as retailer_size,
pd.price,
sp.max_cost,
sp.min_cost
from dim_product as dp
join product_codes as pc on pc.product_id = dp.product_id and pc.deleted_ind = 'N'
join suspect_products as sp on sp.product_id = dp.product_id
left join (
select
nvl(json_extract_path_text(rf."raw",'brand_name'),dei.brand_name) as brand_name,
nvl(json_extract_path_text(rf."raw",'name'),dei.name) as product_name,
nvl(json_extract_path_text(rf."raw",'size'), dei.size) as size,
nvl(json_extract_path_text(rf."raw",'cost_price_per_unit'),dei.cost_price_per_unit::VARCHAR) as price,
nvl(rf.code,dei.lookup_code) as code,
nvl(rf.retailer_id,dei.warehouse_id) as retailer_id
from product_retailer_file_data as rf
left join (
select
d.brand_name,
d.name,
d.size,
d.cost_price_per_unit,
d.lookup_code,
d.warehouse_id
from data_entry_items as d
join (
select lookup_code, max(created_at) as max_date
from data_entry_items
where created_at > current_date-720
group by 1) as m on m.lookup_code = d.lookup_code and m.max_date = d.created_at
) as dei on dei.lookup_code = rf.code and dei.warehouse_id = rf.retailer_id
) as pd on pd.code = pc.code and pd.retailer_id = pc.warehouse_id
order by 1;

Group data monthly and city

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)

Combining two queries in mySQL

I'm trying to combine the results of two queries. I'm not very proficient in mysql so I'm here for some help.
The first query is as follows:
select count(roomtypeid) as bookedrooms, day
from event_guest_hotel
where hotelid = 1 and roomtypeid = 1
group by day;
This returns:
The second query:
SELECT ehr.reservationid, ehr.day, h.name AS hotelname,
ehr.totalrooms as requested_rooms, r.name AS roomname
FROM event_hotel_reservation ehr
INNER JOIN hotel_room_type r
ON ehr.roomtypeid = r.roomtypeid
INNER JOIN hotel h
ON ehr.hotelid = h.hotelid
WHERE totalRooms != 0
AND reservationID = '1'
This returns:
Can I combine the first query with the second one, so I get the results of the first one in another resultcolumn next to 'roomname'? That way I know how many rooms are already booked and how many were originally requested from one single query.
Try:
SELECT ehr.reservationid, ehr.day, h.name AS hotelname,
ehr.totalrooms as requested_rooms, r.name AS roomname,
egh.bookedrooms
FROM event_hotel_reservation ehr
INNER JOIN hotel_room_type r ON ehr.roomtypeid = r.roomtypeid
INNER JOIN hotel h ON ehr.hotelid = h.hotelid
left outer join (
select hotelid, count(roomtypeid) as bookedrooms, day
from event_guest_hotel
where roomtypeid = 1
group by hotelid, day
) egh on h.hotelid = egh.hotelid and ehr.day = egh.day
WHERE totalRooms != 0
AND reservationID = '1'