Firstly, the relationships between the tables in question:
I'm attempting to write a query which retrieves: people_has_trips.people_personID, people_has_trips_tripID, seminarname, agent, and "Amount," which is intended to be the total of all entries in the Payments table for a given entry in the Trip table. This is relevant because this query is meant to be used in a subform on the Access frontend I'm building. In simple terms, the concept for this query is: Which trip(s) has this person been on, and how much money was spent, total, on each trip?
Here's my code so far:
SELECT
people_has_trips.people_PersonID,
people_has_trips.trips_tripID,
people_has_trips.seminar_seminarID,
seminar.seminarname,
agentref.agent,
payments.amount
FROM
(seminar
INNER JOIN (((trips
INNER JOIN people_has_trips ON trips.tripID = people_has_trips.Trips_tripID)
INNER JOIN payments ON trips.tripID = payments.trips_tripID)
INNER JOIN agentnotes ON trips.tripID = agentnotes.Trips_tripID) ON seminar.seminarid = people_has_trips.seminar_seminarid)
INNER JOIN
agentref ON trips.agentref_agentid = agentref.agentid;
Which returns the following:
So we're most of the way there, obviously the final version will be cleaned up a bit (seminarID is unneccesary, for example), so my only question is: what do I need to do so that instead of "amount" showing every individual payment, it's a total of all payments for a trip?
Bonus: The keen-eyed will notice that "seminar" is actually a optional foreign key, and therefore this query, being made of inner joins, excludes any combination of people and trips which does not include a seminar. This is not intended, and another problem I'll need to solve.
Sorry for rearranging the SQL, but I had a hard time following what was going on until I reorganised it.
If you GROUP BY the columns other than the payment value you can use aggregate functions like SUM to get the total of the payments.
SELECT
people_has_trips.people_PersonID,
people_has_trips.trips_tripID,
people_has_trips.seminar_seminarID,
seminar.seminarname,
agentref.agent,
SUM(payments.amount)
FROM seminar
INNER JOIN people_has_trips
ON
people_has_trips.seminar_seminarid = seminar.seminarid
INNER JOIN trips
ON
people_has_trips.Trips_tripID = trips.tripID
INNER JOIN payments
ON
trips.tripID = payments.trips_tripID
INNER JOIN agentnotes
ON
agentnotes.Trips_tripID = trips.tripID
INNER JOIN agentref
ON
agentref.agentid = trips.agentref_agentid
GROUP BY
people_has_trips.trips_tripID,
people_has_trips.people_PersonID,
people_has_trips.seminar_seminarID,
seminar.seminarname,
agentref.agent
;
Related
I believe I have formed this question title correctly because I wasn't sure how to form it. As an example, I have summarized my query below.
I have an order table which saves order details like customer id, address and product ids and quantity ordered for each order in a row. So multiple inventory/product ids are saved in a single row.
so my query looks like: this is a summarized query for an easier explanation I have omitted various other fields.
SELECT customer.name,customer.address,tbl_order.order_date,tbl_order.product1_id,tbl_order.product2_id,inventory.product1_name,inventory.product2_name
FROM tbl_order
INNER JOIN customer ON tbl_order.customer_id = customer.id
INNER JOIN inventory on tbl_order.product1_id = inventory.id
INNER JOIN inventory on tbl_order.product2_id = inventory.id
where YEAR(tbl_order.order_date)='$year'
So my question is how to get the inventory details from the inventory table based on each product id from tbl_order. I am running a while loop to show all data for a year
while($row=mysqli_fetch_assoc($sql1))
I can divide this query into 2 and run the inventory query individually but then how to combine the while loop, as sometimes there could also be empty query when some products are not in order table (depending on order to order, not all products are ordered) so this doesn't work
while($row=mysqli_fetch_assoc($sql1)) and ($row1=mysqli_fetch_assoc($inv1)) and ($row2=mysqli_fetch_assoc($inv2))
and so one for 10 products
First, of all you have bad DB design and I kindly advice to normalize your DB.
Second, if you can not re-design the DB you can use multiple joins with aliases like:
SELECT
customer.name, customer.address, tbl_order.order_date,
tbl_order.product1_id, inv1.product1_name,
tbl_order.product2_id, inv2.product2_name
FROM tbl_order
INNER JOIN customer ON tbl_order.customer_id = customer.id
INNER JOIN inventory AS inv1 ON tbl_order.product1_id = inv1.id
INNER JOIN inventory AS inv2 ON tbl_order.product2_id = inv2.id
WHERE YEAR(tbl_order.order_date)='$year'
I have the following tables in my database.I only listed the important columns which can be used for joining.
I need to get the following output
Currently I'm using two seperate queries for each COUNT value
For assigned licenses
select
products.id,products.name,COUNT(assigned_licenses.id)
from
deployment_users
inner join
assigned_licenses
on
deployment_users.id = assigned_licenses.deployment_user_id
inner join
products
on
assigned_licenses.id = products.id
and
deployment_users.customer_id = 10
group by
assigned_licenses.id
;
For total licenses
select
products.id,products.name,COUNT(total_licenses.id)
from
customers
inner join
total_licenses
on
customers.iccode = licenses.iccode
inner join
products
on
total_licenses.id = products.id
and
customers.id = 10
group by
total_licenses.id
;
Since there are more than a 1,000 products that need to be listed,I want to combine them into a single query.How can I do that?
Your specification leaves some room for interpretation (e.g. can a user have assigned licenses without total licenses? if yes my query will fail.) but I would go with this.
SELECT
products.id,
products.name,
Count(Distinct total_licenses.id) As CountTotalLicenses,
Count(Distinct assigned_liceses.deployment_users_id) As CountAssignedLicenses
FROM products
LEFT JOIN total_licenses ON total_licenses.products_id = products.id
LEFT JOIN customers ON customers.iccode = total_licenses.customers_iccode
LEFT JOIN assigned_licenses ON assigned_liceses.total_licenses_id = total_licenses.id
WHERE
customers.id = 10
GROUP BY
products.id,
products.name
For the future it would be awesome if you could paste code as code and not as an image. People cannot simple copy paste snippets of your code and have to type everything again...
Try joining Both of your query
SELECT * FROM (
(First Query) as assigned_licn
INNER JOIN
(Second Query) as total_licn
USING (id)
);
I have the following database example:
The example is pretty much self-explanatory: There are lessons held by teachers at defined time periods (time_start, time_end) each time period -> lesson connection has its own max_students number.
I know want to list all lessons with all information of the 3 tables (and the max_students). I would do it like that (I heard, that joining table like that is the fastest way):
SELECT * FROM lesson, teacher, time, teacher_has_lesson, time_has_lesson
WHERE lesson.lesson_id = teacher_has_lesson.lesson_lesson_id
AND teacher.teacher_id = teacher_has_lesson.teacher_teacher_id
AND lesson.lesson_id = time_has_lesson.lesson_lesson_id
AND time.time_id = time_has_lesson.time_time_id
1.) Is this a good solution if you just want to join 3 tables or are there better ones?
2.) This SQL call will get me only lessons, that have a teacher and a time. I also want to display lessons, that are in the database, but dont have a teacher or time yet. How can I do that?
There's an alternative way of writing this using join syntax. What you have is equivalent to an inner join, where you only see rows where there are matches:
select
*
from
lesson l
inner join
teacher_has_lesson tl
on l.lession_id = tl.lesson_lesson_id
inner join
teacher t
on tl.teacher_teacher_id = t.teacher_d
inner join
time_has_lesson tml
on l.lesson_id = tml.lesson_lesson_id
inner join
time tm
on tml.time_time_id = tm.time_ud
There's another type of join called outer join, where all the rows from one table are shown, and null values supplied if there are no matching values in the other table. It comes in two or three variants. left outer join shows all rows from the first table. right outer join shows all rows from the second table. full outer join shows all rows from both tables. So, for your second query you could use:
select
*
from
lesson l
left outer join
teacher_has_lesson tl
on l.lession_id = tl.lesson_lesson_id
left outer join
teacher t
on tl.teacher_teacher_id = t.teacher_d
left outer join
time_has_lesson tml
on l.lesson_id = tml.lesson_lesson_id
left outer join
time tm
on tml.time_time_id = tm.time_ud
Join Orders, Staff's first and last name, item and location into one so I can export the content into an Excel spreadsheet.
SELECT orders.order_id, staff.staff_id, staff.first_name, staff.last_name, items.name, locations.address1, locations.address2, locations.state, locations.zip_code, orders.created_at
FROM orders
INNER JOIN staff
ON orders.staff_id = staff.staff_id
INNER JOIN items
ON orders.item_id = items.item_id
INNER JOIN location_staff
ON location_staff.staff_id = staff.staff_id
INNER JOIN locations
ON location_staff.loc_id = location.loc_id
I am trying to gather this information to put into an excel document but my query is not returning any results. Any help would be appreciated.
Here is An ERD diagram for further understanding
https://www.dropbox.com/s/7inma4s42xq5t4a/ERD.jpg
(Location_staff_link was shortened when created to location_staff)
jsut remove the extra tables in your FROM clause,
SELECT orders.order_id,
staff.staff_id,
staff.first_name,
staff.last_name,
items.name,
orders.created_at
FROM orders
INNER JOIN staff
ON orders.staff_id = staff.staff_id
INNER JOIN items
ON orders.item_id = items.item_id
INNER JOIN locations
ON location.staff_id = staff.staff_id
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
Nothing in your query looks bad, so here is what I suggest to find the answer in this sort of case.
First reduce to the bare minimum of the first join and change the fields to select * (temporarily, you can go back to the real fields as soon as you find the issue) so you can se all the data.
Do you get records, then add in any where clauses on the tables in that join. Do you still get records?
Then add in each join and each where clause one at a time until you find the one where the records disappear. This will tell you what you need to do to fix it.
Often in a case like this where no records are returned, one of the joins needs to be a left join or there is no data that meets the terms of the where clauses or one of the joins is improperly defined. And sometimes, there is a problem in that your database does not have the data you were expecting it to have. But first you have to use the process above to diagnose where the problem is.
I'm having a bit of a hiccup regarding a particular SQL query. I need to join data from two tables, while also limiting the data (but not necessarily grabbing it) by means of a third table. The tables are as follows:
MEMBERS(member_id,first_name,last_name)
MEMBERS_GROUPS(member_id,group_id)
CHARGES(charge_id,member_id,charge_amount,status)
I need to find all charges for all members of a specific group but I also want to grab the first and last name from the MEMBERS table. The query I've come up with thus far is:
select c.*, m.first_name, m.last_name
FROM charges c
LEFT JOIN member m
ON c.member_id=m.member_id
INNER JOIN members_groups mg
ON mg.group_id=1
i've also tried:
SELECT c.*, m.first_name, m.last_name
FROM charges c, members_groups mg, member m
WHERE c.member_id=mg.member_id
AND mg.group_id = 1
AND c.status='Valid'
AND c.member_id = m.member_id
…but neither returns the data I need. I'm sure I'm overthinking this, but I can't for the life of me get the correct values. I keep getting what appears to be the Cartesian product -- regardless, it's clearly returning too many rows and bad data.
Perhaps what you need is to also restrict the INNER JOIN on members_groups to
those rows with mg.member_id = m.member_id:
SELECT c.*, m.first_name, m.last_name
FROM charges c
LEFT JOIN member m
ON c.member_id=m.member_id
INNER JOIN members_groups mg
ON mg.group_id=1
AND mg.member_id = m.member_id