Grouping within a view - mysql

This is something I'm trying to get my head around... I have three tables like this:
Practice
* PracticeID
* PracticeName
Group
* GroupID
* Sales
* Salaries
* Overheads
Values
* PracticeID
* GroupID
* Income
* Expense
What I am looking to do is prepare a view to sum up the income and expenses in Values by the group names in the Group table. I can get as far as a row by row summary, but I'm having the issue on how to include the group clause in the code I currently have, which is below:
SELECT Practice.PracticeName, Group.Groupname, Values.Income, Values.Expenses
FROM values INNER JOIN
Practice ON values.PracticeID = Practice.PracticeID INNER JOIN
Group ON Values.NominalGroupID = Group.GroupID

try this:
SELECT Practice.PracticeName, Group.Groupname, SUM(Values.Income) as SumIncome, SUM(Values.Expenses ) as SumExpences
FROM values INNER JOIN
Practice ON values.PracticeID = Practice.PracticeID INNER JOIN
Group ON Values.NominalGroupID = Group.GroupID
Group By Group.Groupname

Your table definition does not really include all the columns you used in your example so I'm not sure if that's what you are looking for:
SELECT Group.Groupname
,SUM(Values.Income) as Income
,SUM(Values.Expenses ) as Expenses
FROM Group
INNER JOIN Value ON Values.GroupID = Group.GroupID
Group By Group.Groupname

Related

MySql sum DISTINCT after join

I have 2 table that join together ( Orders and Order_item)
When I use join I get duplicates records then I eliminate them with DISTINCT, but when I want to get sum the the shipping_price DISTINCT not works because it just eliminate the same price value and I all my prices are same I get 1 not sum !
If I don't use DISTINCT , I get rows per each items in order
SELECT sum(DISTINCT shipping_price) FROM `product_order`
INNER JOIN `product_address`
ON `product_order`.`address_id` = `product_address`.`id`
INNER JOIN `product_item`
ON `product_order`.`id` = `product_item`.`order_id`
WHERE (`status`<>2)
AND (`company_id`=1968)
AND DATE(date)='2021-08-31'
ORDER BY `product_order`.`id` DESC
how to get sum of shipping price correctly ..
data in order_table is
id shipping_price status
100
200
200
100
sum = 600 , but how to get it, if I did't DISTINCT, I get more than one row per order_items row counts that join tho order..
Use a subquery to get your shipping prices. Something like this:
SELECT product_order.id,
SUM(product_item.price * product_item.quantity) shipping_price
FROM product_order
JOIN product_item ON product_order.id = product_item.order_id
GROUP BY product_order.id
The trick here is to get a subquery that delivers exactly one row per order, with the summed-up shipping priced in it. Do your SUM() ... GROUP BY ...` in the subquery. That way you'll avoid any duplication of items.
TEST THIS before you proceed to make sure it works: giving each order id and its shipping price.
Then use it as if it were a table, JOINing it to the rest.
SELECT total.shipping_price,
product_order.id,
product_address.*
FROM product_order
JOIN product_address
ON product_order.id = product_address.order_id
JOIN (
SELECT product_order.id,
SUM(product_item.price * product_item.quantity) shipping_price
FROM product_order
JOIN product_item ON product_order.id = product_item.order_id
GROUP BY product_order.id
) total ON product_order.id = total.id
ORDER BY product_order.id = total.id
Use a subquery instead of a join.
SELECT (
select sum(shipping_price)
FROM product_item
WHERE po.`id` = `product_item`.`order_id`
) as shipping_price
FROM `product_order` po
INNER JOIN `product_address`
ON `product_order`.`address_id` = `product_address`.`id`
WHERE (`status`<>2)
AND (`company_id`=1968)
AND DATE(date)='2021-08-31'
ORDER BY `product_order`.`id` DESC

LEFT JOIN SUM with WHERE clause

The following query always outputs SUM for all rows instead of per userid. Not sure where else to look. Please help.
SELECT * FROM assignments
LEFT JOIN (
SELECT SUM(timeworked) AS totaltimeworked
FROM time_entries
) assignments ON (userid = assignments.userid AND ticketid = ?)
WHERE ticketid = ?
ORDER BY assigned,scheduled
If you want to keep the SELECT *, you would have to add a group by clause in the subquery. Something like this
SELECT * FROM assignments
LEFT JOIN (
SELECT SUM(timeworked) AS totaltimeworked
FROM time_entries
GROUP BY userid
) time_entriesSummed ON time_entriesSummed.userid = assignments.userid
WHERE ticketid = ?
ORDER BY assigned,scheduled
But a better way would be to change the SELECT * to instead select the fields you want a add a group by clause directly. Something like this
SELECT
assignments.id,
assignments.assigned,
assignments.scheduled,
SUM(time_entries.timeworked) AS totalTimeworked
FROM assignments
LEFT JOIN time_entries
ON time_entries.userid = assignments.userid
GROUP BY assignments.id, assignments.assigned, assignments.scheduled
Edit 1
Included table names in query 2 as mentioned in chameera's comment below

Sql query to combine result of two tables

Currently I am using the following query to display the following result.
SELECT * FROM RouteToGrowthRecord, GradeMaster,MileStoneMaster
WHERE MemberID = 'ALV01L11034A06' AND
RouteToGrowthRecord.GradeID=GradeMaster.GradeID AND
RouteToGrowthRecord.MileStoneID=MileStoneMaster.MileStoneID
ORDER BY CheckupDate DESC
Now I have another table named RouteToGrowthRecord_st that has same
columns as RouteToGrowthRecord with some additional fields.
I need to display result that are present in both the table. ie . if RouteToGrowthRecord_st has 3 records with the given menberID,then output must contain 3 more records along with the above query result.(fr ex above its 9+3=12 records in total).
You can use Union here to merge the results getting from both queries. Use default values for the unmapped additional fields.
You can write above query in following way
SELECT * FROM RouteToGrowthRecord
INNER JOIN GradeMaster ON RouteToGrowthRecord.GradeID=GradeMaster.GradeID
INNER JOIN MileStoneMaster ON RouteToGrowthRecord.MileStoneID=MileStoneMaster.MileStoneID
LEFT JOIN RouteToGrowthRecord_st ON RouteToGrowthRecord_st.memberID=RouteToGrowthRecord.memberID
WHERE
RouteToGrowthRecord.MemberID = 'ALV01L11034A06'
order by CheckupDate DESC
this is my answer
SELECT CheckUpDate,AgeInMonths,PresentWeight,Height,Diagnosis,growthstatus,GradeName,MilestoneName,MemberID
FROM RouteToGrowthRecord, GradeMaster,MileStoneMaster WHERE
MemberID = 'ALV01L56107A11 ' and
RouteToGrowthRecord.GradeID=GradeMaster.GradeID and
RouteToGrowthRecord.MileStoneID=MileStoneMaster.MileStoneID
union
SELECT CheckUpDate,AgeInMonths,PresentWeight,Height,Diagnosis,growthstatus,GradeName,MilestoneName,MemberID
FROM RouteToGrowthRecord_st, GradeMaster,MileStoneMaster WHERE
MemberID = 'ALV01L56107A11 ' and
RouteToGrowthRecord_st.GradeID=GradeMaster.GradeID and
RouteToGrowthRecord_st.MileStoneID=MileStoneMaster.MileStoneID
order by CheckupDate DESC
SELECT * FROM RouteToGrowthRecord a inner join GradeMaster b inner
join MileStoneMaster c inner join RouteToGrowthRecord_st d on
a.GradeID=b.GradeID AND a.MileStoneID=c.MileStoneID and
d.GradeID=b.GradeID AND d.MileStoneID=c.MileStoneID
WHERE a.MemberID = 'ALV01L11034A06'
ORDER BY CheckupDate DESC

JOINing Three SQL Tables?

I have a working SQL query, but I need to grab another piece of data from a third table in the query for ease of use, but have been unable to grab it.
Every table is basically tied together by tenant_id
(I apologize for the bad structure, I didn't create the DB)
TABLE: tenant_statements
tenant_id balance property date
TABLE: leases
lease_id tenant_id property unit_number
TABLE: tenants
tenant_id first_name last_name global_comment
My current query:
SELECT *
FROM tenant_statements t
INNER JOIN (
SELECT *
FROM leases
GROUP BY tenant_id
ORDER BY lease_id
)l ON t.tenant_id = l.tenant_id
WHERE t.date = '$date'
AND t.property = '$property'
ORDER BY t.balance DESC
This give's me the appropriate response for joining the two tables: leases and tenant_statements. $date and $property are set via a PHP variable loop and used for presentation.
What I am attempting to do is also grab tenants.global_comment and have it added each result.
the ideal output will be:
tenant_statements t: t.balance, t.date
leases l: l.property, l.unit_number
tenants x: x.first_name, x.last_name, x.global_comment
All in one query.
Can anyone point me in to the right direction? Thank you!
How about something like
SELECT *
FROM tenant_statements t INNER JOIN
(
SELECT *
FROM leases
GROUP BY tenant_id
ORDER BY lease_id
)l ON t.tenant_id = l.tenant_id INNER JOIN
tenants ts ON t.tenant_id = ts.tenant_id
WHERE t.date = '$date'
AND t.property = '$property'
ORDER BY t.balance DESC
Although each join specification joins only two tables, FROM clauses can contain multiple join specifications. This allows many tables to be joined for a single query.
SELECT t.tenant_id,
t.balance,
l.unit_number,
l.property
x.first_name, x.last_name, x.global_comment
fROM tenant_statements t
INNER JOIN leases l ON l.tenant_id = t .tenant_id
INNER JOIN tenants x on x.tenant_id = t.tenant_id

MySQL views cannot have subquery in from, and don't maintain order. How can I create a view from this query?

I'm essentially trying to obtain a resultset with each employee's current title. I'd like to create a view from this for later use, but I find I'm being stumped, and likely missing a simple solution. Here's the query in question, and thanks in advance!
select * from
(SELECT
appointment.employee_id,
title.`name` as title_name
FROM
appointment
INNER JOIN appointment_title ON appointment.id = appointment_title.appointment_id
INNER JOIN title ON appointment_title.title_id = title.id
order by appointment_title.effective_date DESC) tmp group by employee_id
Updated:
SELECT
appointment.employee_id ,
( SELECT title.`name`
FROM appointment_title
INNER JOIN title
ON appointment_title.title_id = title.id
WHERE appointment.id = appointment_title.appointment_id
ORDER BY appointment_title.effective_date DESC
LIMIT 1
) AS title_name
FROM appointment
GROUP BY appointment.employee_id
Another option is to break up the query into two views. The first view will contain the derived table subquery, and the second will simply select from that one:
CREATE VIEW vwEmployee_Inner AS
SELECT
appointment.employee_id,
title.`name` as title_name
FROM
appointment
INNER JOIN appointment_title ON appointment.id = appointment_title.appointment_id
INNER JOIN title ON appointment_title.title_id = title.id
order by appointment_title.effective_date DESC
And then your original view becomes:
CREATE VIEW vwEmployee AS
SELECT * FROM vwEmployee_Inner GROUP BY employee_id