I have a problem with database query?
Here is the Scenario
This is a TeacherClass Table (Parent Table)(id)
And This is a ClassSchedule Table(Child table)(teacher_class_id is a foreign key)
I want to find out the the latest date from ClassSchedule Table for each class and order by class_schdule_date(latest date).
(It would be better for me if you write the query in cackphp query syntax.)
Please Help me.
This requires a straightforward join:
select tc.id, max(schedule_date) as max_schedule_date
from TeacherClass tc
left join ClassSchedule cs on cs.teacher_class_id = tc.id
group by tc.id
You can select other columns from the TeacherClass table as you like - just add them to the group by clause too.
Note that left join is required in case there are no scheduled dates for the class, you still get a row for the class (but the max scheduled date will be null)
Use this solution:
SELECT
c.*, b.*
FROM
(
SELECT teacher_class_id, MAX(schedule_date) AS maxdate
FROM classschedule
GROUP BY teacher_class_id
) a
INNER JOIN
classschedule b ON
a.teacher_class_id = b.teacher_class_id AND
a.maxdate = b.schedule_date
INNER JOIN
teacherclass c ON
b.teacher_class_id = c.teacher_class_id
Related
I have table for transactions, transaction_properties, transaction_inventories. inventories.
`transactions:`
id, name, qty
`transaction_properties:`
transaction_id, property_id
`transaction_inventory:`
transaction_id, inventory_id
`inventories:`
id, name, property_id
My task is to get all transaction according my property id.
property_id gets data from inventory that gets data from transaction_inventory, also gets data from transaction_properties and finally I get all transaction_ids to get them from transaction table.
Please do not consider to change table architecture. This style is a must for this project.
Check the following query:
select inv.*,t.*,tran_pro.*,tran_inv.* from inventories as inv
left join on transation as t on t.id on tran_pro.transtaion_id
left join on transaction_properties as tran_pro on t.id = tran_pro.transaction_id
left join on transaction_invertory as tran_inv on t.id = tran_inv.transaction_id
where inv.property_id = ''
Note:Keep all ids as primary key
I don't know, it should be fairly simple if you have attempted to solve the problem or looked up how joins work. Unless I am missing any other detail.
select t.id, t.name, invt.id, tp.property_id
from inventories invt
inner join transactions_inventory ti
on invt.id = ti.inventory_id
inner join transaction_properties tp
on tp.transaction_id = ti.transaction_id
inner join transactions t
on t.id = tp.transaction_id
I'm trying to left join the second table useri_ban based on the users' ids, with the extra condition: useri_ban.start_ban = max_start.
In order for me to calculate max_start, I have to run the following subquery:
(SELECT MAX(ub.start_ban) AS max_start, user_id FROM useri_ban ub WHERE ub.user_id = useri.id)
Furthermore, in order to add max_start to every row, I need to inner join this subquery's result into the main result. However, it seems that once I apply that join, the subquery is no longer able to access useri.id.
What am I doing wrong?
SELECT
useri.id as id,
useri.email as email,
useri_ban.warning_type_id as warning_type_id,
useri_ban.type as type,
useri.created_at AS created_at
FROM `useri`
inner join
(SELECT MAX(ub.start_ban) AS max_start, user_id FROM useri_ban ub WHERE ub.user_id = useri.id) `temp`
on `useri`.`id` = `temp`.`user_id`
left join `useri_ban` on `useri_ban`.`user_id` = `useri`.`id` and `useri_ban`.`start_ban` = `max_start`
Does this solve your problem? You need GROUP BY in the inner query instead of another join.
SELECT useri.id, useri.email, maxQuery.maxStartBan
FROM useri
INNER JOIN
(
SELECT useri_ban.user_id ubid, MAX(useri_ban.startban) maxStartBan
FROM useri_ban
GROUP BY useri_ban.user_id
) AS maxQuery
ON maxQuery.ubid = useri.id;
I have somehow complicated query as follow:
SELECT w,e2.EntityID
FROM (SELECT EntityID,SUM(frequency) w
FROM omid.entity_epoch_data where EpochID in
( select id from epoch where startDateTime>='2013-11-01 00:00:00' and
startDateTime <= '2013-11-30 00:00:00')
GROUP BY EntityID) e1
RIGHT JOIN
entity e2 ON e1.EntityID = e2.EntityID order by w desc
And it works properly but as soon as I add another innerjoin:
SELECT w,e2.EntityID
FROM (SELECT EntityID,SUM(frequency) w
FROM omid.entity_epoch_data inner join omid.entity_dataitem_relation as e3 on(e1.EntityID = e3.EntityID)
where e3.dataitemtype=3 and EpochID in
( select id from epoch where startDateTime>='2013-11-01 00:00:00' and
startDateTime <= '2013-11-30 00:00:00')
GROUP BY EntityID) e1
RIGHT JOIN
entity e2 ON e1.EntityID = e2.EntityID order by w desc
I get the following error:
column 'EntityID' in the field set is ambiguous
Does anyone have an idea where my mistake is?
Update :
I have the right version as follow (it gives me exactly what I want)
SELECT ID,e2.EntityID,e2.Name,AVG(intensity),AVG(quality),SUM(frequency)
FROM omid.entity_epoch_data as e1
right JOIN entity AS e2 ON (e1.EntityID = e2.EntityID)
where EpochID in
( select id from epoch where startDateTime>='2013-11-01 00:00:00' and
startDateTime <= '2013-11-30 00:00:00') and e1.EntityID in
(SELECT entityid FROM omid.entity_dataitem_relation where dataitemtype=3)
group by e2.EntityID order by sum(frequency) desc;
But it takes time and I need to change the
(SELECT entityid FROM omid.entity_dataitem_relation where dataitemtype=3)
group by e2.EntityID order by sum(frequency) desc;
to innerjoin can anyone help me how to do that?
Image:
You have two problems.
First off, the syntax for that first INNER JOIN is not correct. You are conflating the INNER JOIN and ON parts of the statement. (At least, I think this is the case, unless you actually have "." characters in your table names are really want a cartesian result from this JOIN)>
Secondly, the second usage of EntityID (in that new INNER JOIN you added) could refer to the EntityID value from either the left or right side of the INNER JOIN -- that's what the "ambiguous column" in the error means.
Here is some SQL to get you started. It follows the selection logic you give in the comment, below. It names each table with an alias and ensures that each column specifies the table from which it should be drawn. I don't have an instance of MySQL handy to try it, but it should get you started.
SELECT E.EntityID, SUM(EED.Frequency)
FROM entity_epoch_data EED INNER JOIN entity_dataitem_relation EDR
ON EED.EntityID = EDR.EntityID WHERE EDR.entity_dataitemtype = 3
RIGHT OUTER JOIN entity E ON E.EntityID = EED.EntityID
GROUP BY E.EntityID
Maybe there are fields named EntityID in both tables - omid.entity_epoch_data and omid.entity_dataitem_relation ?
Your first query had only one take in the subquery to look for entityid, but the second query has two tables in the subquery.
Also, you are referencing table e1 inside a subquery before e1 is defined.
give the tables a specific alias name and that error will go away.. because you have two columns that are not distinguished, so when you try to use one it doesn't know which table to pull it from
Everything in the following query results in one line for each invBlueprintTypes row with the correct information. But I'm trying to add something to it. See below the codeblock.
Select
blueprintType.typeID,
blueprintType.typeName Blueprint,
productType.typeID,
productType.typeName Item,
productType.portionSize,
blueprintType.basePrice * 0.9 As bpoPrice,
productGroup.groupName ItemGroup,
productCategory.categoryName ItemCategory,
blueprints.productionTime,
blueprints.techLevel,
blueprints.researchProductivityTime,
blueprints.researchMaterialTime,
blueprints.researchCopyTime,
blueprints.researchTechTime,
blueprints.productivityModifier,
blueprints.materialModifier,
blueprints.wasteFactor,
blueprints.maxProductionLimit,
blueprints.blueprintTypeID
From
invBlueprintTypes As blueprints
Inner Join invTypes As blueprintType On blueprints.blueprintTypeID = blueprintType.typeID
Inner Join invTypes As productType On blueprints.productTypeID = productType.typeID
Inner Join invGroups As productGroup On productType.groupID = productGroup.groupID
Inner Join invCategories As productCategory On productGroup.categoryID = productCategory.categoryID
Where
blueprints.techLevel = 1 And
blueprintType.published = 1 And
productType.marketGroupID Is Not Null And
blueprintType.basePrice > 0
So what I need to get in here is the following table with the columns below it so I can use the values timestamp and sort the entire result by profitHour
tablename: invBlueprintTypesPrices
columns: blueprintTypeID, timestamp, profitHour
I need this information with the following select in mind. Using a select to show my intention of the JOIN/in-query select or whatever that can do this.
SELECT * FROM invBlueprintTypesPrices
WHERE blueprintTypeID = blueprintType.typeID
ORDER BY timestamp DESC LIMIT 1
And I need the main row from table invBlueprintTypes to still show even if there is no result from the invBlueprintTypesPrices. The LIMIT 1 is because I want the newest row possible, but deleting the older data is not a option since history is needed.
If I've understood correctly I think I need a subquery select, but how to do that? I've tired adding the exact query that is above with a AS blueprintPrices after the query's closing ), but did not work with a error with the
WHERE blueprintTypeID = blueprintType.typeID
part being the focus of the error. I have no idea why. Anyone who can solve this?
You'll need to use a LEFT JOIN to check for NULL values in invBlueprintTypesPrices. To mimic the LIMIT 1 per TypeId, you can use the MAX() or to truly make sure you only return a single record, use a row number -- this depends on whether you can have multiple max time stamps for each type id. Assuming not, then this should be close:
Select
...
From
invBlueprintTypes As blueprints
Inner Join invTypes As blueprintType On blueprints.blueprintTypeID = blueprintType.typeID
Inner Join invTypes As productType On blueprints.productTypeID = productType.typeID
Inner Join invGroups As productGroup On productType.groupID = productGroup.groupID
Inner Join invCategories As productCategory On productGroup.categoryID = productCategory.categoryID
Left Join (
SELECT MAX(TimeStamp) MaxTime, TypeId
FROM invBlueprintTypesPrices
GROUP BY TypeId
) blueprintTypePrice On blueprints.blueprintTypeID = blueprintTypePrice.typeID
Left Join invBlueprintTypesPrices blueprintTypePrices On
blueprintTypePrice.TypeId = blueprintTypePrices.TypeId AND
blueprintTypePrice.MaxTime = blueprintTypePrices.TimeStamp
Where
blueprints.techLevel = 1 And
blueprintType.published = 1 And
productType.marketGroupID Is Not Null And
blueprintType.basePrice > 0
Order By
blueprintTypePrices.profitHour
Assuming you might have the same max time stamp with 2 different records, replace the 2 left joins above with something similar to this getting the row number:
Left Join (
SELECT #rn:=IF(#prevTypeId=TypeId,#rn+1,1) rn,
TimeStamp,
TypeId,
profitHour,
#prevTypeId:=TypeId
FROM (SELECT *
FROM invBlueprintTypesPrices
ORDER BY TypeId, TimeStamp DESC) t
JOIN (SELECT #rn:=0) t2
) blueprintTypePrices On blueprints.blueprintTypeID = blueprintTypePrices.typeID AND blueprintTypePrices.rn=1
You don't say where you are putting the subquery. If in the select clause, then you have a problem because you are returning more than one value.
You can't put this into the from clause directly, because you have a correlated subquery (not allowed).
Instead, you can put it in like this:
from . . .
(select *
from invBLueprintTypesPrices ibptp
where ibtp.timestamp = (select ibptp2.timestamp
from invBLueprintTypesPrices ibptp2
where ibptp.blueprintTypeId = ibptp2.blueprintTypeId
order by timestamp desc
limit 1
)
) ibptp
on ibptp.blueprintTypeId = blueprintType.TypeID
This identifies the most recent records for all the blueprintTypeids in the subquery. It then joins in the one that matches.
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