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
Related
Summary
I am attempting to LEFT JOIN on a filtered TABLE in SQL.
To do so I am first declaring a temporary table in an # variable, then attempting to join on it later.
Unfortunately I am not having much luck doing this, it massively speeds up my query when limiting to such a resultset.
Other Routes Tried
I initially was trying to conduct this on the WHERE, however this was preventing rows from occurring where there were no matching events (I am counting the events by intervals_days so I need to return regardless of whether there's matching in the other).
After I realised my mistake, I moved to the ON. I have not seen examples of this done, and I have a feeling doing a FIND_IN_SET here on a SELECT would not be performant?
QUERIES
The Initial Filter
DECLARE #filtered_events TABLE (id INT, eventable_id INT, eventable_type VARCHAR(255), occurred_at TIMESTAMP, finished_at TIMESTAMP)
INSERT INTO #filtered_events
SELECT
e.id, e.eventable_id, e.eventable_type, e.occurred_at, e.finished_at
FROM
units_events as ue
LEFT JOIN
events as e
ON
e.id = ue.event_id
WHERE
ue.unit_id
IN
(1,2,3);
Ignore the (1,2,3) here, these values are added to the query dynamically.
My Attempted Use Of It
SELECT
i.starts_at as starts_at,
i.ends_at as ends_at,
count(fe.id) as count
FROM
intervals_days as i
LEFT JOIN
#filtered_events as fe
ON
( fe.occurred_at >= starts_at AND fe.occurred_at < ends_at )
WHERE
( starts_at >= '15-01-2019' AND ends_at < NOW() )
GROUP BY
starts_at
ORDER BY
starts_at
DESC;
These queries are within one SQL document, one above the other with the terminating ; semicolon on each.
I expect this to output what my lower query outputs (a grouped resultset by the intervals_days rows)- however with the benefit of my LEFT JOIN query being conducted on a much smaller sample.
Sorry, no such syntax.
MySQL has no concept of arrays, either.
Nor can you use DECLARE outside of a Stored Routine.
As Shadow said in the comments, with MySQL I would use a subquery like this:
SELECT
i.starts_at as starts_at,
i.ends_at as ends_at,
count(fe.id) as count
FROM
intervals_days as i
LEFT JOIN
(
SELECT
e.id,
e.eventable_id,
e.eventable_type,
e.occurred_at,
e.finished_at
FROM units_events as ue
LEFT JOIN events as e
ON e.id = ue.event_id
WHERE ue.unit_id IN (1,2,3)
) fe
ON ( fe.occurred_at >= starts_at AND fe.occurred_at < ends_at )
WHERE ( starts_at >= '15-01-2019' AND ends_at < NOW() )
GROUP BY starts_at
ORDER BY starts_at
DESC;
http://sqlfiddle.com/#!9/e6effb/1
I'm trying to get a top 10 by revenue per brand for France on december.
There are 2 tables (first table has date, second table has brand and I'm trying to join them)
I get this error "FUNCTION db_9_d870e5.SUM does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual"
Is my use of Inner join there correct?
It's because you had an extra space after SUM. Please change it from
SUM (o1.total_net_revenue)to SUM(o1.total_net_revenue).
See more about it here.
Also after correcting it, your query still had more error as you were not selecting order_id on your intermediate table i2 so edited here as :
SELECT o1.order_id, o1.country, i2.brand,
SUM(o1.total_net_revenue)
FROM orders o1
INNER JOIN (
SELECT i1.brand, SUM(i1.net_revenue) AS total_net_revenue,order_id
FROM ordered_items i1
WHERE i1.country = 'France'
GROUP BY i1.brand
) i2
ON o1.order_id = i2.order_id AND o1.total_net_revenue = i2.total_net_revenue
AND o1.total_net_revenue = i2.total_net_revenue
WHERE o1.country = 'France' AND o1.created_at BETWEEN '2016-12-01' AND '2016-12-31'
GROUP BY 1,2,3
ORDER BY 4
LIMIT 10`
--EDIT stack Fan is correct that the o2.total_net_revenue exists. My confusion was because the data structure duplicated three columns between the tables, including one that was being looked for.
There were a couple errors with your SQL statement:
1. You were referencing an invalid column in your outer-select-SUM function. I believe you're actually after i2.total_net_revenue.
The table structure is terrible, the "important" columns (country, revenue, order_id) are duplicated between the two tables. I would also expect the revenue columns to share the same name, if they always have the same values in them. In the example, there's no difference between i1.net_revenue and o1.total_net_revenue.
In your inner join, you didn't reference i1.order_id, which meant that your "on" clause couldn't execute correctly.
PROTIP:
When you run into an issue like this, take all the complicated bits out of your query and get the base query working correctly first. THEN add your functions.
PROTIP:
In your GROUP BY clause, reference the actual columns, NOT the column numbers. It makes your query more robust.
This is the query I ended up with:
SELECT o1.order_id, o1.country, i2.brand,
SUM(i2.total_net_revenue) AS total_rev
FROM orders o1
INNER JOIN (
SELECT i1.order_id, i1.brand, SUM(i1.net_revenue) AS total_net_revenue
FROM ordered_items i1
WHERE i1.country = 'France'
GROUP BY i1.brand
) i2
ON o1.order_id = i2.order_id AND o1.total_net_revenue = i2.total_net_revenue
AND o1.total_net_revenue = i2.total_net_revenue
WHERE o1.country = 'France' AND o1.created_at BETWEEN '2016-12-01' AND '2016-12-31'
GROUP BY o1.order_id, o1.country, i2.brand
ORDER BY total_rev
LIMIT 10
This is my mysql query
SELECT tm.MAGAZINE_ID, tm.MAGAZINE_NAME,tm.MAGAZINE_DESCRIPTION,pub.publisher_name,
tmi.COVER_PAGE_THUMB AS COVER_PAGE_VERTICAL,tmi.FROM_DATE AS ISSUE_DATE,
tm.html_flag AS HTML_EXIST,tm.CATEGORY_ID,tm.language_id,tm.is_free,tma.AppUrl,
(SELECT issue_id from tbl_magazine_issue WHERE magazine_id = 141
ORDER BY FROM_DATE DESC LIMIT 1) as temp_issue_id
FROM tbl_magazine_apps as tma
LEFT OUTER JOIN tbl_magazine_code as tmc ON tmc.Code = tma.AppsCode
LEFT OUTER JOIN `tbl_magazine` AS tm ON tmc.magazine_Id = tm.MAGAZINE_ID
JOIN `tbl_magazine_issue` AS tmi ON temp_issue_id = tmi.issue_id
LEFT OUTER JOIN mst_publisher AS pub ON tm.publisher_id=pub.publisher_id
WHERE
tmi.PUBLISH_STATUS IN(1,3)
AND tmi.`OS_SELECT` = '".$osType."'
AND tma.id IN (".$appIds.")
GROUP BY tm.MAGAZINE_ID
ORDER BY tmi.ISSUE_DATE DESC
but i got an error that
#1054 - Unknown column 'temp_issue_id' in 'on clause'
if any one know about this please help me. i am new to this
AFAIK The subquery belongs to the from part:
http://dev.mysql.com/doc/refman/5.7/en/from-clause-subqueries.html
So I would join the subquery.
Like:
SELECT a.a, b.b
FROM table1 as a
JOIN (SELECT b from table2) as b ON a.key = b.key;
As the message suggests, the column temp_issue_id is not in any of the following tables: tbl_magazine_apps, tbl_magazine, or tbl_magazine_issue. It is also not a variable in the environment.
Beyond that, it is pretty much impossible for anyone to figure out how to fix the problem without more knowledge about the data structure.
If I were to hazard a guess, based on the table names, that particular join would be:
JOIN `tbl_magazine_issue` AS tmi ON tm.magazine_id = tmi.magazine_id
because it makes sense to me that a magazine issue would be connect to a magazine. I have no idea what temp_issue_id is, though.
temp_issue_id give alias name for specifying this column i think it should be tm.issue_id
temp_issue_id is column's name as per the query. You need it to convert to table and use subsequent column in your SELECT clause.
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 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