I have two tables from the same database:
Table READINGS:
Table SENSORS:
I'm trying to create a query that will return, for each sensor registered in SENSORS, it's last row registered in READINGS. Note that the same sensor can have many registers in READINGS, but ONLY ONE in SENSORS.
The result should be something like:
Dump of the database: https://dl.dropboxusercontent.com/u/85576999/redeSensores.sql
http://sqlfiddle.com/#!9/95818/5
SELECT readings.*
FROM readings
INNER JOIN sensors
ON sensors.idSensor = readings.sensorid
LEFT JOIN readings r
ON r.sensorid = readings.sensorid
AND r.`datetime` > readings.`datetime`
WHERE r.id IS NULL
Or if you need info from both tables:
http://sqlfiddle.com/#!9/95818/6
SELECT readings.*,
sensors.*
FROM readings
INNER JOIN sensors
ON sensors.idSensor = readings.sensorid
LEFT JOIN readings r
ON r.sensorid = readings.sensorid
AND r.`datetime` > readings.`datetime`
WHERE r.id IS NULL
UPDATE AVG last day
http://sqlfiddle.com/#!9/95818/10
SELECT t.*,
AVG(r_avg.temperature),
AVG(r_avg.pollution),
AVG(r_avg.noise),
AVG(r_avg.humidity)
FROM (SELECT readings.*, sensors.*
FROM readings
INNER JOIN sensors
ON sensors.idSensor = readings.sensorid
LEFT JOIN readings r
ON r.sensorid = readings.sensorid
AND r.`datetime` > readings.`datetime`
WHERE r.id IS NULL
) t
LEFT JOIN readings r_avg
ON t.sensorid = r_avg.sensorid
AND r_avg.`datetime` >= DATE_ADD(t.datetime,INTERVAL -1 DAY)
GROUP BY t.id;
UPDATE 2 To filter aggregated records you can use HAVING:
http://sqlfiddle.com/#!9/95818/11
HAVING AVG(r_avg.temperature)!=42
Related
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.
I have a database with table Plane, the table Flight, which is basically a Flight that a Plane did, then for each flight I have solved M:N table which just holds foreign keys for Flight and Destination, 2 entries in table Destination, to know the difference between Departure and Arrival, table Destination has a connection to table Type( Departure and Arrival, which is set in another table, of 2 rows, "Zacetna" = Departure, "Koncna" = Arrival ). Table Destination also has a connection to table Date which contains Datetime.
I want to Subtract Arrival and Departure time for each Flight, then Sum the times if Plane has multiple Flights.
I have tried to just Subtract them all and then sub but that didn't work, then I have tried to Group By, but with no luck.
In the attached picture.
Plane called "Falcon FX 3000" has 2 flights, idFlight 5 and 6. To get the expected result I would have to do
( Destination_6_Date - Destination_5_Date) + (Destination_4_Date - Destination_7_Date)
but none of my solutions worked
SELECT d.Ime, letD.Destinacija_idDestinacija, l.idLet,tip.Tip, t.Termin
FROM Letalo p
INNER JOIN Let l ON l.Letalo_idLetalo = p.idLetalo
INNER JOIN Let_Has_Destinacija letD on letD.Let_idLet = l.idLet
INNER JOIN Destinacija d on d.idDestinacija = letD.Destinacija_idDestinacija
INNER JOIN Termin t on t.idTermin = d.Termin_idTermin
INNER JOIN Tip_Destinacije tip on tip.idTip_Destinacije = Tip_Destinacije_idTip_Destinacije WHERE p.Naziv='Falcon FX 3000';
https://i.imgur.com/5r2G9yI.png
https://i.imgur.com/3CIfbUN.png
Sorry for the ERDiagram for being in the different language
Letalo = Plane
Let = Flight
Let_Has_Destinacija = Solved M:N, holding Flight ID and Destination ID
Destinacija = Destination
Termin = Date
Tip_Destinacija = Type
EDIT
This is the successful GROUP BY query that returns valid calculations, now I just need to sum them. I am guessing this will be done with subquery, but I don't really understand that, as I am new to MySQL
SELECT d.Ime as Name, letD.Destinacija_idDestinacija as Destination, l.idLet as idFlight,tip.Tip as Type, CAST(t.Termin as DATE), timediff(Max(t.Termin), min(t.Termin))
FROM Letalo p
INNER JOIN Let l ON l.Letalo_idLetalo = p.idLetalo
INNER JOIN Let_Has_Destinacija letD on letD.Let_idLet = l.idLet
INNER JOIN Destinacija d on d.idDestinacija = letD.Destinacija_idDestinacija
INNER JOIN Termin t on t.idTermin = d.Termin_idTermin
INNER JOIN Tip_Destinacije tip on tip.idTip_Destinacije = Tip_Destinacije_idTip_Destinacije WHERE p.Naziv='Falcon FX 3000'
GROUP BY l.idLet;
https://i.imgur.com/hUXZDnQ.png
EDIT 2
By using temp tables, I managed to SUM the flights times, but I have to use 2 queries for this, which is not what I want.
DROP TABLE IF EXISTS tempTime;
CREATE TEMPORARY TABLE tempTime (
SELECT timediff(Max(t.Termin), min(t.Termin)) as FlightTime
FROM Letalo p
INNER JOIN Let l ON l.Letalo_idLetalo = p.idLetalo
INNER JOIN Let_Has_Destinacija letD on letD.Let_idLet = l.idLet
INNER JOIN Destinacija d on d.idDestinacija = letD.Destinacija_idDestinacija
INNER JOIN Termin t on t.idTermin = d.Termin_idTermin
INNER JOIN Tip_Destinacije tip on tip.idTip_Destinacije = Tip_Destinacije_idTip_Destinacije WHERE p.Naziv='Falcon FX 3000'
GROUP BY l.idLet);
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(FlightTime))) as FlownTime FROM tempTime;
DROP TABLE IF EXISTS tempTime;
https://i.imgur.com/HlPtgHr.png
ACCEPTED ANSWER
SELECT
`Name`,
`Destination`,
`Type`,
`Date`,
SEC_TO_TIME(SUM(TIME_TO_SEC(`Time_diff`))) as `Tot_Diff`
FROM (
SELECT
d.`Ime` as `Name`,
letD.`Destinacija_idDestinacija` as `Destination`,
l.`idLet` as idFlight,tip.`Tip` as `Type`,
CAST(t.`Termin` as DATE) as `Date`,
timediff(Max(t.`Termin`), min(t.`Termin`)) as `Time_diff`
FROM Letalo p
INNER JOIN `Let` l
ON l.`Letalo_idLetalo` = p.`idLetalo`
INNER JOIN `Let_Has_Destinacija` letD
on letD.`Let_idLet` = l.`idLet`
INNER JOIN `Destinacija` d
on d.`idDestinacija` = letD.`Destinacija_idDestinacija`
INNER JOIN `Termin` t
on t.`idTermin` = d.`Termin_idTermin`
INNER JOIN `Tip_Destinacije` tip
on tip.`idTip_Destinacije` = `Tip_Destinacije_idTip_Destinacije`
WHERE p.Naziv = 'Falcon FX 3000'
GROUP BY l.idLet
) as `main`
I believe this should produce the result you describe. Basically, it takes the query you have, uses it as a sub-query
then sums the time differences.
SELECT
`Name`,
`Destination`,
`Type`,
`Date`,
SEC_TO_TIME(SUM(TIME_TO_SEC(`Time_diff`))) as `Tot_Diff`
FROM (
SELECT
d.`Ime` as `Name`,
letD.`Destinacija_idDestinacija` as `Destination`,
l.`idLet` as idFlight,tip.`Tip` as `Type`,
CAST(t.`Termin` as DATE) as `Date`,
timediff(Max(t.`Termin`), min(t.`Termin`)) as `Time_diff`
FROM Letalo p
INNER JOIN `Let` l
ON l.`Letalo_idLetalo` = p.`idLetalo`
INNER JOIN `Let_Has_Destinacija` letD
on letD.`Let_idLet` = l.`idLet`
INNER JOIN `Destinacija` d
on d.`idDestinacija` = letD.`Destinacija_idDestinacija`
INNER JOIN `Termin` t
on t.`idTermin` = d.`Termin_idTermin`
INNER JOIN `Tip_Destinacije` tip
on tip.`idTip_Destinacije` = `Tip_Destinacije_idTip_Destinacije`
WHERE p.Naziv = 'Falcon FX 3000'
GROUP BY l.idLet
) as `main`
GROUP BY `Name`,`Destination`,`Type`,`Date`;
Hi I am trying to query a table that conatains multiple duplicates on Code,Amount and Status How will I do this if I only one to get a result group according to the client_group name and get the sum of amount under that group
SELECT `client`.`client_group`
, FORMAT(SUM(`Data_result`.`Data_result_amount` ),2) as sum
FROM
`qwer`.`Data_result`
INNER JOIN `qwer`.`Data`
ON (`Data_result`.`Data_result_lead` = `Data`.`Data_id`)
INNER JOIN `qwer`.`Data_status`
ON (`Data_result`.`Data_result_status_id` = `Data_status`.`Data_status_id`)
INNER JOIN `qwer`.`client`
ON (`Data`.`Data_client_id` = `client`.`client_id`)
WHERE `Data_status`.`Data_status_name` IN ('PAID') AND MONTH(`Data_result`.`result_ts`) = MONTH(CURRENT_DATE())
AND YEAR(`Data_result`.`result_ts`) = YEAR(CURRENT_DATE())
GROUP BY `client`.`client_group`
Result of said query:
Table
Try to distinct before run the 'sum' check whether this solve your problem
SELECT `client_group` , FORMAT(SUM(`Data_result_amount` ),2) as sum from (
SELECT DISTINCT `client`.`client_group` , `Data_result`.`Data_result_amount`
FROM
`qwer`.`Data_result`
INNER JOIN `qwer`.`Data`
ON (`Data_result`.`Data_result_lead` = `Data`.`Data_id`)
INNER JOIN `qwer`.`Data_status`
ON (`Data_result`.`Data_result_status_id` = `Data_status`.`Data_status_id`)
INNER JOIN `qwer`.`client`
ON (`Data`.`Data_client_id` = `client`.`client_id`)
WHERE `Data_status`.`Data_status_name` IN ('PAID') AND MONTH(`Data_result`.`result_ts`) = MONTH(CURRENT_DATE())
AND YEAR(`Data_result`.`result_ts`) = YEAR(CURRENT_DATE())
) T
GROUP BY `client_group`
you can check the query here http://sqlfiddle.com/#!9/36a3f8/6
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
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'