I have the following MySQL query:
SELECT p.*,
IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
pm.MediaID,
date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
astext(pg.Geometry) AS Geometry
FROM property p, propertygeometry pg
JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
WHERE p.paused = 0
AND p.PropertyGeometryID = pg.id
GROUP BY p.id
And I'm getting this error:
#1054 - Unknown column 'p.id' in 'on clause'
As far as I can see the query looks right, any idea what could be wrong?
Don't mix ANSI-89 style and ANSI-92 style joins. They have different precedence which can lead to confusing errors, and that is what has happened here. Your query is being interpreted as follows:
FROM property p, (
propertygeometry pg
JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
...
)
In the above, the joins using the JOIN keyword are evaluated first before the comma-style join is even considered. At that point the table p isn't yet declared.
From the MySQL manual:
However, the precedence of the comma operator is less than of INNER JOIN, CROSS JOIN, LEFT JOIN, and so on. If you mix comma joins with the other join types when there is a join condition, an error of the form Unknown column 'col_name' in 'on clause' may occur. Information about dealing with this problem is given later in this section.
I'd recommend always using ANSI-92 style joins, i.e. using the JOIN keyword:
SELECT p.*,
IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
pm.MediaID,
date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
astext(pg.Geometry) AS Geometry
FROM property p
JOIN propertygeometry pg ON p.PropertyGeometryID = pg.id
JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
WHERE p.paused = 0
GROUP BY p.id
Related:
Why isn't SQL ANSI-92 standard better adopted over ANSI-89?
As stated before there is a precedence issue using joins via the comma operator where the LEFT JOIN will be executed and so references to table aliases won't exist at that time. Though you can implicitly tell MySQL to use a JOIN via that statement you may also tell MySQL to evaluate the comma joined tables first, then execute left join thusly:
SELECT p.*,
IF(COUNT(ms.PropertyID) > 0,1,0) AS Contacted,
pm.MediaID,
date_format(p.AvailableFrom, '%d %b %Y') AS 'AvailableFrom',
astext(pg.Geometry) AS Geometry
FROM (property p, propertygeometry pg)
JOIN shortlist sl ON sl.PropertyID = p.id AND sl.MemberID = 384216
LEFT JOIN message ms ON ms.PropertyID = p.id AND ms.SenderID = 384216
LEFT JOIN property_media pm ON pm.PropertyID = p.id AND pm.IsPrimary = 1
WHERE p.paused = 0
AND p.PropertyGeometryID = pg.id
GROUP BY p.id
Notice the comma separated tables are contained within parenthesis (). The table aliases and columns will now be available to your other JOINs.
I bumped into this error unknown column, the diff is the query is built thru HQL inside session.executeQuery("select id, name, sum(paid), custType from cust group by brand") that's why having to manually type inner join or join keyword is not an option as the hql is the one generating it.
it produces a query sumthing like this:
select cust_id, name, sum(paid), c.custTypeId
from customer c, custType ct
on c.custTypeId = ct.custTypeId
it says "unknown c.custTypeId" column when I am 101% sure it bears that column.
My classes/relations:
Customer {
Integer custId
CustomerType custType
}
CustomerType{
Integer custTypeId
string code
}
the problem lies in the comma in "from customer, custType" line. it should be with the word JOIN as the answer stated above. but since it is HQL and is being generated, I can't do that. What I did is modified by query and instead of typing select custType, I typed select custType.id, custType.code
I know it's basic but for first timers like me, it was a struggle.
If this helps someone (and a note to future myself), I was getting this error when trying to execute the following queries in MariaDB:
SELECT a.name, b.name
FROM `cities` as a
INNER JOIN `countries` as b
ON `a.country_id` = `b`.`id`;
whereas I should have written it like:
SELECT a.name, b.name
FROM `cities` as a
INNER JOIN `countries` as b
ON `a`.`country_id` = `b`.`id`;
I'll leave it to the reader to spot the difference as an exercise. :)
Related
I am creating my first left join and I am having syntax errors. I been up and down this list and I cannot figure what is the issue. Here is the setup
I have three tables Mass_List, Parent and Parent_Place. They all have the same ID but I need to get the Date_Close from Mass_List and the ID and Username from Parent, making sure that the user is a paying member, which is know by the column MBSHIP in Parent_Place.
I do the queries separate and they work but when I do the queries together it tells me my syntax is correct but gives me the following error
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I searched online but nothing close to my case. Any idea what's wrong with my syntax? Here is the query
SELECT P.USERNAME, M.DATE_CLOSE, P.ID
FROM MASS_LIST M, PARENT P
WHERE P.ID =
(SELECT M.ID
FROM MASS_LIST M
INNER JOIN PARENT_PLACE PP ON PP.ID = M.ID
WHERE PP.CLASS_USR = 'PAID'
AND M.DATE_CLOSE > getdate()
AND PP.MBSHIP > 0)
AND M.DATE_CLOSE > GETDATE() ORDER BY M.DATE_CLOSE;
I'm not sure why you need the subslect in the first place... Just join all 3 tables together... Though I do find it odd that the "ID" column in each tables is what joins them together. Seems like your trying to join on the PK of each table which isn't the way they should be joined unless each table is truly a 1-1 relationship with the other... then I'd say interesting table design.
SELECT ML.Date_Close, P.ID, P.UserName
FROM mass_List ML
INNER JOIN PARENT P
on ML.ID = P.ID
INNER JOIN PARENT_PLACE PP
on P.ID = PP.ID
WHERE PP.MBSHIP > 0
and PP.Class_user = 'PAID'
and M.Date_Close > getDate()
order by m.date_Close
I've been trying to write some code in SQL, but it keeps coming up with a syntax error regarding the join, and I can't work out why.
SELECT `COUNTRY$`.country_name, `PARTNER$`.partner_name, count(member_id)
FROM `Member$`
Left Join `COUNTRY$`
ON `MEMBER$`.country_id=`COUNTRY$`.country_id
lEFT jOIN `PARTNER$`
on `MEMBER$`.partner_ID = `PARTNER$`.partner_ID
Group By country_name,Partner_name
Any help would be appreciated.
May have something to do with how your table names are in 'thisFormat$'. Also you did not specify which table member_id was coming and group by also doesn't specify which table country_name, partner_name was from.
Try putting aliases on the tablenames and see if that eliminates the problem
SELECT c.country_name, p.partner_name, count(m.member_id)
FROM `Member$` m
left join `COUNTRY$` c on c.country_id = m.country_id
left join `PARTNER$` p on p.partner_id = m.partner_id
GROUP BY c.country_name, p.partner_name
I have a sql statement I've created, and I need to transform it to use explict join operators so that all compare against constant clauses, and only compare against constant clauses, appear in the where clause for the query.
I am not sure how to make this change though, can anyone show me how I would do this? Here is what I have:
select S.sname
from P, J, S, SPJ
where P.pname = 'Bolt'
and J.city = 'London'
and P.p# = SPJ.p#
and J.j# = SPJ.j#
and S.s# = SPJ.s#;
If I understand you, you are looking to convert from sql89 syntax to an inner join.
It would look like this:
select
S.sname
from
P
inner join SPJ on `P.p#` = `SPJ.p#` and P.pname = 'Bolt'
inner join J on `SPJ.j#` = `J.j#` and J.city = 'London'
inner join S on `SPJ.s#` = `S.s#`
I have added the pname and city restrictions to the join syntax because that appears to be what you asked for. These can be left in the where clause as well however.
Also note that extended or special characters in column names in mysql (like p#) must be enclosed in backticks.
You want something like this:
SELECT S.sname
FROM P INNER JOIN SPJ ON P.p#=SPJ.p#
INNER JOIN J ON J.j# = SPJ.j#
INNER JOIN S ON S.s# = SPJ.s#
WHERE P.pname = 'Bolt'
AND J.city = 'London';
The conditions that are used to combine tables are placed in the JOIN clauses, and the other conditions are left in the WHERE clause.
I need to display all fixtures(who plays 'against' who) for a current user so I wrote SQL query
SELECT
fixture.*
FROM
sport_team_player AS team_player, sport_team AS team
INNER JOIN sport_fixture AS fixture
ON (`team_player`.`team_id` = fixture.`team1_id` OR `team_player`.`team_id` = fixture.`team2_id`)
WHERE
team_player.`team_id` = team.`team_id` AND team_player.`player_id` = '16'
And this doesn't work and tells me that team_player.team_id does not exist
but if I join the second table instead of selecting from multiple tables it works just fine.
PS. This is not the best way to write such query but it's generated by ORM module..
EDIT:
Result would be list of fixture data like
------------------------------
|fixture_id|team1_id|team2_id|
------------------------------
|1 | 2 | 3 |
------------------------------
Try this one. Should result to the same query as yours;
SELECT fixture.*
FROM sport_team_player AS team_player
JOIN sport_team AS team
ON team_player.`team_id` = team.`team_id` AND team_player.`player_id` = '16'
INNER JOIN sport_fixture AS fixture
ON (`team_player`.`team_id` = fixture.`team1_id`
OR `team_player`.`team_id` = fixture.`team2_id`)
You shouldn't mix up both notations when building up joins. The comma you are using to join team_player and team , and the subsequent calls to inner join, will most probably trigger unknown column error.
Precedence of the comma operator is less than of INNER JOIN, CROSS JOIN, LEFT JOIN. That's why when you mix comma with other join table operators [Unknown column 'col_name' in 'on clause'] error occur. Same query will work if you specify the cross join ( to get a Cartesian product of the first two tables) instead of commas, because then in the from clause the table operators will be evaluated from left to right:
SELECT
fixture.*
FROM
sport_team_player AS team_player
cross join sport_team AS team
INNER JOIN sport_fixture AS fixture
ON (team_player.team_id = fixture.team1_id OR team_player.team_id = fixture.team2_id)
WHERE
team_player.team_id = team.team_id AND team_player.player_id = '16'
E.g.:
SELECT f.*
FROM sport_team_player p
JOIN sport_team t
ON t.team_id = p.team_id
JOIN sport_fixture f
ON p.team_id IN(f.team1_id,f.team2_id)
WHERE p.player_id = 16;
I will try to explain things as much as I can.
I have following query to fetch records from different tables.
SELECT
p.p_name,
p.id,
cat.cat_name,
p.property_type,
p.p_type,
p.address,
c.client_name,
p.price,
GROUP_CONCAT(pr.price) AS c_price,
pd.land_area,
pd.land_area_rp,
p.tagline,
p.map_location,
r.id,
p.status,
co.country_name,
p.`show`,
u.name,
p.created_date,
p.updated_dt,
o.type_id,
p.furnished,
p.expiry_date
FROM
property p
LEFT OUTER JOIN region AS r
ON p.district_id = r.id
LEFT OUTER JOIN country AS co
ON p.country_id = co.country_id
LEFT OUTER JOIN property_category AS cat
ON p.cat_id = cat.id
LEFT OUTER JOIN property_area_details AS pd
ON p.id = pd.property_id
LEFT OUTER JOIN sc_clients AS c
ON p.client_id = c.client_id
LEFT OUTER JOIN admin AS u
ON p.adminid = u.id
LEFT OUTER JOIN sc_property_orientation_type AS o
ON p.orientation_type = o.type_id
LEFT OUTER JOIN property_amenities_details AS pad
ON p.id = pad.property_id
LEFT OUTER JOIN sc_commercial_property_price AS pr
ON p.id = pr.property_id
WHERE p.id > 0
AND (
p.created_date > DATE_SUB(NOW(), INTERVAL 1 YEAR)
OR p.updated_dt > DATE_SUB(NOW(), INTERVAL 1 YEAR)
)
AND p.p_type = 'sale'
everything works fine if I exclude GROUP_CONCAT(pr.price) AS c_price, from above query. But when I include this it just gives one result. My intention to use group concat above is to fetch comma separated price from table sc_commercial_property_price that matches the property id in this case p.id. If the records for property exist in sc_commercial_property_price then fetch them in comma separated form along with other records. If not it should return blank. What m I doing wrong here?
I will try to explain again if my problem is not clear. Thanks in advance
The GROUP_CONCAT is an aggregation function. When you include it, you are telling SQL that there is an aggregation. Without a GROUP BY, only one row is returns, as in:
select count(*)
from table
The query that you have is acceptable syntax in MySQL but not in any other database. The query does not automatically group by the columns with no functions. Instead, it returns an arbitrary value. You could imagine a function ANY, so you query is:
select any(p.p_name) as p_num, any(p.tagline) as tagline, . . .
To fix this, put all your current variables in a group by clause:
GROUP BY
p.p_name,
p.id,
cat.cat_name,
p.property_type,
p.p_type,
p.address,
c.client_name,
p.price,
pd.land_area,
pd.land_area_rp,
p.tagline,
p.map_location,
r.id,
p.status,
co.country_name,
p.`show`,
u.name,
p.created_date,
p.updated_dt,
o.type_id,
p.furnished,
p.expiry_date
Most people who write SQL think it is good form to include all the group by variables in the group by clause, even though MySQL does not necessarily require this.
Add GROUP BY clause enumerating whatever you intend to have separate rows for. What happens now is that it picks some value for each result column and group_concats every pr.price.