Reputation: 2094
I am calculating average petrol quantity per month from two tables truck and order. So far I am getting average per month, which I am able to get by order by date and average of average in outer SQL.
I want to get the same value, only now it should return all details of orders. I will be using this to map to java using Row mapper for a one to many relationship and a dto class that has list of orders.
select truckId, truckcode, purchasedDate, descriptions, avg(avgPetrolQty) as avgPerMonth from (
SELECT t.truckId, t.truckCode, t.purchasedDate, t.descriptions,
COALESCE(monthname(orderDate),'Not Announced') as month,
IFNULL (avg(petrolQty),0) as avgPetrolQty
from truck t left join orderz o
on t.truckId = o.truckId
where t.truckId = :t.truckId
group by t.truckCode, orderDate,
year(orderDate)
) group by truckcode
So far this gives me as expected average per month single value for each truck, but I want to add the remaining details of order to it, like full join which should get by id. I tried this but obviously not accurate
select t.truckId, t.truckCode, t.purchasedDate,
t.descriptions, o.orderId, o.petrolQty, o.orderDate, avg(avgPetrolQty) as avgPerMonth, o.truckId from (truck t
SELECT t.truckId, t.truckCode, t.purchasedDate, t.descriptions, o.orderId, o.petrolQty, o.orderDate, o.truckId
COALESCE(monthname(o.orderDate),'Not Announced') as month,
IFNULL (avg(o.petrolQty),0) as avgPetrolQty
left join orderz o
on t.truckId = o.truckId
where t.truckId = :t.truckId
group by t.truckId, o.orderDate
)
from truck t left join orderz o
on t.truckId = o.truckId
where T.truckId = :t.truckId
group by t.truckId, o.orderDate
Average per month is the most important information. Now I just want to get a full detail of truck (this means and all orders that belong to the truck)
SQL table
DROP TABLE IF EXISTS truck;
CREATE TABLE truck (
truckId INT NOT NULL AUTO_INCREMENT,
truckCode VARCHAR(255) NOT NULL UNIQUE,
purchasedDate timestamp NOT NULL,
descriptions VARCHAR(255) NOT NULL,
PRIMARY KEY (truckId)
);
DROP TABLE IF EXISTS orderz;
CREATE TABLE orderz (
orderId INT NOT NULL AUTO_INCREMENT,
petrolQty DOUBLE NOT NULL,
orderDate timestamp NOT NULL,
truckId INT,
PRIMARY KEY (orderId),
FOREIGN KEY (truckId) REFERENCES truck(truckId)
ON UPDATE CASCADE
ON DELETE CASCADE
);
Upvotes: 1
Views: 77
Reputation: 2094
To do this your outer query should serve as more or less a copier , so you do all the work in the inner query and copy to outer select statement only thing specific the outer select statement will do is to get average of the average.
select truckId, truckCode, purchasedDate,
descriptions, orderId, petrolQty, orderDate, avg(avgPetrolQty) as avgPerMonth, truckId from (
SELECT t.truckId, t.truckCode, t.purchasedDate, t.descriptions, o.orderId, o.petrolQty, o.orderDate,
COALESCE(monthname(o.orderDate),'Not Announced') as month,
IFNULL (avg(o.petrolQty),0) as avgPetrolQty
from truck t left join orderz o
on t.truckId = o.truckId
where t.truckId = :t.truckId
group by t.truckCode, o.orderId, o.orderDate
) group by truckCode, orderId
And this is how i have mapped it in java using RowMapper and namedParameterJdbcTemplate to get by id
public TruckFullDetailDto getTruckFullDetailById (final Integer id) {
SqlParameterSource namedParameterSource =
new MapSqlParameterSource("t.truckId", id);
TruckDetailMapper mapper = new TruckDetailMapper();
namedParameterJdbcTemplate.query(fullTruckDetailsql, namedParameterSource, mapper);
TruckFullDetailDto truck = mapper.getDetail();
return truck;
}
/**
* This is mapper maps one to many relationship.
*/
public class TruckDetailMapper implements RowMapper<TruckFullDetailDto> {
private TruckFullDetailDto detail;
public TruckFullDetailDto mapRow(ResultSet rs, int rowNum)
throws SQLException {
if (detail == null) {
this.detail = new TruckFullDetailDto();
detail.setTruckId(rs.getInt("truckId"));
detail.setTruckCode(rs.getString("truckCode"));
detail.setAvgPerMonth(rs.getDouble("avgPerMonth"));
detail.setDescriptions(rs.getString("descriptions"));
detail.setPurchasedDate(rs.getDate("purchasedDate"));
}
Order order = new Order ();
order.setOrderId(rs.getInt("orderId"));
order.setPetrolQty(rs.getDouble("petrolQty"));
order.setOrderDate(rs.getDate("orderDate"));
order.setTruckId(rs.getInt("truckId"));
this.detail.getOrderList().add(order);
return null;
}
private TruckFullDetailDto getDetail() {
return detail;
}
}
Upvotes: 1