Compare database value to number of rows in another table - php

For each item in the first table, there is a 'numberOf' field. The value of this field must have an identical number of rows in a related table. These are like reservation rows so multiple users can book the item at the same time. This syncronisation sometimes goes out and there are more rows than the 'numberOf' field variable, and vice versa.
So I want to display a table that outputs the 'numberOf' from the first table, and the amount of rows that correspond to it from the other table. They are linked by the Item ID. Hope this isn't too confusing. The query is output with a do while loop. Here is the query I have so far anyway:
$querySync = sprintf("SELECT
COUNT(reserve_id), item_id, details, numberOf
FROM
reservations
JOIN
items ON item_id = itemID_reserved
WHERE
itemID_reserved = 1 ");
So at the moment it counts the number of rows in the reservations table. It then joins the items table so I can display the description and numberOf etc. Of course at the moment it only outputs the item with ID 1. But I can't seem to get it to go though each item, check its numberOf, and compare it to the number of rows in reservations table.
The idea is to have it all on one column and at the end of the row print if it is out of sync etc. I then need to rebuild the rows in the reservations table to match the numberOf.
Sorry thats a long one!

SELECT COUNT(reserve_id), item_id, details, numberOf,
COUNT(reserve_id) > numberOf AS overbook
FROM items
LEFT JOIN
reservations
ON itemID_reserved = item_id
GROUP BY
item_id

It might be easier to just directly calculate which items are "out of sync":
select i.item_id
from reservations r JOIN items i on (i.item_id = r.itemID_reserved)
group by i.item_id
having count(r.itemID_reserved) > i.numberOf
I'm making some assumptions there about which tables have which fields, but it should be sufficiently illustrative.

Related

How to use Select query result (array) to the new query and display result for each value?

I want to fetch the item name from one table and use that name to calculate the the value using name from another table.
I am using select query to fetch the result rows:
SELECT itemname FROM tablename
I want to use the result array or array value one by one to run my next query.
SELECT SUM(quantity) as inward FROM inward_details WHERE item_name='$itemname'
There are 3 tables,
Item
Inward
outward
What I want to do is get the item list from the item table with select query then get the quantity for the item from inward and the quantity from outward then subtract the inward quantity from outward quantity and echo result.
E.g item name is pen and inward quantity is 20 and outward quantity is 5,
Then I want to display result as pen 15 (20-5)
But I want it for all the items from item table.
You could use hidden input in HTML with the row values inside within a while or for loop, this means that the inputs won't be shown in the browser. With back-end code(PHP) you can easily execute math calculations and proceed to insert. Hope this helps :-)
You can get the results you want with only one query, using a LEFT JOIN:
SELECT t.itemname,
COALESCE(SUM(i.quantity), 0) AS inward,
COALESCE(SUM(o.quantity), 0) AS outward,
COALESCE(SUM(i.quantity), 0) - COALESCE(SUM(o.quantity), 0) AS movement
FROM tablename t
LEFT JOIN inward_details i ON i.item_name = t.itemname
LEFT JOIN outward_details o ON o.item_name = t.itemname
GROUP BY t.itemname
We use a LEFT JOIN so that if there are no inward_details rows associated with an item we still get a row, and we COALESCE the SUM so that a NULL result for that situation results in a 0 value.

How to Query and Arrange Two Similar Tables

I have one student table links to two scores tables which are exactly the same structures. The only different is that one table will stores high scores, the other table stores low scores. Now I need to query both high and low score tables, it will list all subjects scores with student name if it is from high score table and scores with name is student if its from low score table, and I need to order the result by time.
SELECT u.student_name,
a.subject1_score,
a.subject2_score,
a.subject3_score,
a.subject4_score,
a.subject5_score,
a.exam_date
FROM Student u
INNER JOIN High_Score_Table a
On u.student_id = a.student_id
ORDER BY a.exame_date = time
Then for low_score_Table I will have almost same query except that the student name will equal to Student by default.
Then I will need to put this together in a list and order by time. How could I do that shorter and better ?
Btw, I can merge two tables low and high_score into one, and add a column called "flag" into that, whenever the flag value equal to "show" then I show student name with all score records, else "hidden" I will just show "Student" and all score records. How could I do that in one query ?
It sounds like you need a UNION, because you are concatenating two distinct result sets - one from High_Score_Table and one from (presumably) Low_Score_Table:
select s.student_name,
h.subject1_score,
h.subject2_score,
h.subject3_score,
h.subject4_score,
h.subject5_score,
h.exam_date
from High_Score_Table h
join Student s on h.student_id = u.student_id
union all
select 'student' as student_name,
l.subject1_score,
l.subject2_score,
l.subject3_score,
l.subject4_score,
l.subject5_score,
l.exam_date
from Low_Score_Table l
order by exam_date
The takeaway here is an ORDER BY clause in a union sorts over the entire result set - which is in this case exactly what you want.

Adding a column to SQL result with AVG from another column in another table based on a condition

Im working on a report in PHP where i have to display the top results for average score for students based on condition for career, status and period, plus dinamic results... The average comes from another table.
Tables: cllg_student_assign. This table has an ID, which is referenced in table cllg_student_assign_course, which has a column SCORE_ACCU. I need to put together the row from cllg_student_assign with the AVG() of SCORE_ACCU from cllg_student_assign_course where FK_ASSIGN=cllg_student_assign.ID.
Im trying this:
SELECT *
FROM cllg_student_assign
LEFT JOIN (SELECT a.FK_ASSIGN, AVG(a.SCORE_ACCU) as SCORE
FROM cllg_student_assign_course as a, cllg_student_assign as b
WHERE b.ID=a.FK_ASSIGN) as score_table
ON cllg_student_assign.ID=score_table.FK_ASSIGN
WHERE STATUS=1
ORDER BY SCORE DESC
Im getting the rows, but i get the average of the whole SCORE_ACCU column in the table, and it puts it only on 1 record... I need each row to have a colum SCORE with its own AVG pulled from the other table.
I have worked with SQL before, but only basic stuff...
Help!

Get and order based on most recent entry while in multiple mysql joins

I have the following statement that finds all the players of a team in the current season. The players are ordered by their handicap. If their handicaps are the same they are ordered by the oldest added_date, meaning newer members are lower down the list.
SELECT players.playerid_p,
players.fname,
players.sname,
players.tel,
players.mob,
players.email,
season_players.captain
FROM season_players
LEFT JOIN players ON (season_players.playerid_f = players.playerid_p)
LEFT JOIN handicaps ON (handicaps.playerid_f = players.playerid_p)
WHERE season_players.seasonid_f = '$currentSeason'
AND season_players.teamid_f = '".$row["teamid_p"]."'
GROUP BY players.playerid_p
ORDER BY handicaps.handicap ASC, handicaps.added_date ASC
The handicaps table can have multiple entries per player for any reviews they have had.
I can't figure out how to make the latest handicap to be used for the ordering (something maybe to do with MAX on added_date?) yet at the same time if two or more handicaps are the same it order them by oldest registered first based on added_date.
In stead of trying to figure out how to satisfy your needs in current query, wouldn't it be an option to create a separate table, let's say "Handicaps_latest", which only stores player_id and required info of latest review. The reason for doing this is because you are only trying to get(columns in your select clause) the information about players and nothing really needed from handicaps table. In this case, a handicaps table with multiple entries per player might not be a good table to join. But considering that those data might be required in other logic, so leave them there and create a branch new table only storing latest review data could be an option for your case. But it requires some extra work apparently, that is, whenever you insert a new entry into your original handicpas table, a particular entry in handicaps_latest needs to be updated.
SELECT x.*
FROM my_table x
JOIN
( SELECT id,MAX(other_column) max_other_column FROM my_table GROUP BY id) y
ON y.id = x.id
AND y.max_other_column = x.other_column;

How do I JOIN these tables?

I have two tables:
**WEEK**
-id
-week #
**ITEM**
-id
-name
-is_marked
-week #
My final desired result is to have a table that has a rowspan="3" table cell with week # in it, followed by the three results for each week from SELECT * FROM item WHERE week = week_number AND is_marked = 1
I don't know if I need to JOIN anything because I don't really need any data from the WEEK table, but I can't quite get how I'd loop through the results to get the desired output. Thoughts?
Ok, some thoughts.
Do you really need a week table in database? What purpose does it serve? It seems like a value for the item table. Its not really an entity, so may not need a separate table IMO.
You are right in that there is nothing to join in the two tables. If the Item table had week_id in it, instead of number, that would make sense, except for my comments in 1
Why only 3 items from each week? If you really want that, I would recommend you order by week number in item table. You can discard the other values in code. Use the order by clause in this case.
Or, you can loop through all the values in week table, for each, select from item table using week number. You can use the limit clause to return only 3 items.
Change your item table to hold the week id and not the value.
then you can do a simple join by doing:
select i.name
from item i
inner join week w on w.id = i.id
where w.week = '2' and i.is_marked = '1'

Categories