Column ALIAS not recognized in HAVING clause, unkown column error - mysql

SELECT u.*, zz.contid, zz.lng, zz.lat, zz.zip, zz.city, zz.state, (**calc distance**) AS distance
FROM contacts zz
INNER JOIN users u
ON zz.id = u.id
WHERE cond1 = 1, cond2=2, etc..
GROUP BY u.id
HAVING MIN(distance) < 100
Error: unknown column distance
Any idea why this is? and how to fix it?
I appreciate any advice, many thanks in advance!

What database is this? If it's something like MSSQL, you can't use aliases like that elsewhere in a query. You'll have to replicate the whole alias definition:
SELECT big+ugly+calculation AS foo
...
HAVING (big+ugly_calculation) = bar
Or wrap the query in another:
SELECT *
FROM ( SELECT *, big+ugly+calculation AS foo )
WHERE foo = bar

You can't refer to an alias in an aggregate function. Move the query into a subquery, and then aggregate it in the outer query.
SELECT *
FROM (
SELECT u.*, zz.contid, zz.lng, zz.lat, zz.zip, zz.city, zz.state, (**calc distance**) AS distance
FROM contacts zz
INNER JOIN users u
ON zz.id = u.id
WHERE cond1 = 1, cond2=2, etc..) subquery
GROUP BY id
HAVING MIN(distance) < 100

Related

LEFT JOIN SUM with WHERE clause

The following query always outputs SUM for all rows instead of per userid. Not sure where else to look. Please help.
SELECT * FROM assignments
LEFT JOIN (
SELECT SUM(timeworked) AS totaltimeworked
FROM time_entries
) assignments ON (userid = assignments.userid AND ticketid = ?)
WHERE ticketid = ?
ORDER BY assigned,scheduled
If you want to keep the SELECT *, you would have to add a group by clause in the subquery. Something like this
SELECT * FROM assignments
LEFT JOIN (
SELECT SUM(timeworked) AS totaltimeworked
FROM time_entries
GROUP BY userid
) time_entriesSummed ON time_entriesSummed.userid = assignments.userid
WHERE ticketid = ?
ORDER BY assigned,scheduled
But a better way would be to change the SELECT * to instead select the fields you want a add a group by clause directly. Something like this
SELECT
assignments.id,
assignments.assigned,
assignments.scheduled,
SUM(time_entries.timeworked) AS totalTimeworked
FROM assignments
LEFT JOIN time_entries
ON time_entries.userid = assignments.userid
GROUP BY assignments.id, assignments.assigned, assignments.scheduled
Edit 1
Included table names in query 2 as mentioned in chameera's comment below

How to select from two tables based on a where clause

I am trying to select from two tables and join them where they have the same id but my query seems wrong that it searches for so long that it crashed workbench.
SELECT s.id,
s.title,
s.votes,
t.*
FROM movies_two.movie s,
movies_one.movie t
LEFT JOIN movies_two.movie
ON movies_one.id = s.id -- not sure which join to use
WHERE s.votes = -1 AND
t.numofvotes > 0;
I have two databases containing similar data. I am trying to select rows that from movies_one and movies_two that have the same id and where movies_one has votes = -1 and movies_two has movies > 0
You don't need a left join for this. Nor do you need a cross join (which is what the comma does in the from clause.
I think you want something like this:
SELECT *
FROM movies_one.movie m1 JOIN
movies_two.movie m2
ON m1.id = m2.id AND
m1.votes = -1 AND
m2.numofvotes > 0;
I would also suggest that you use table aliases that are abbreviations for the table names. Your text description of what you wand and your query are quite different.
SELECT s.id ,s.title, s.votes, t.*
FROM movies_two.movie s
JOIN movies_one.movie t
ON t.id = s.id
WHERE s.votes =-1
AND t.numofvotes >0;
Would be okay.
You use a left join, when you only want the data in movies_two.movie - the left table. But here you want the data of both tables.
Try this:
SELECT *
FROM movies_one.movie
WHERE numofvotes = -1
UNION
SELECT *
FROM movies_two.movie
WHERE votes > 0

MySQL query - unknown column in where clause- column value might not yet be determined when the WHERE clause is executed

SELECT area_id,
area_name,
(select count(*) from applications
where claims_status=1 and
center_name=c.area_id) as cont
FROM apparea c where cont<>0
I am trying to get fields and relevant count from anothere table, but the above query is not working. The query is involved two different tables(apparea, applications). The above query has error and I am looking for the alternate way to achieve this.
The alias for your column cont is not available in the WHERE clause. You will want to use something similar to this:
SELECT area_id,
area_name,
cont
FROM
(
SELECT area_id,
area_name,
(select count(*)
from applications
where claims_status=1
and center_name=c.area_id) as cont
FROM apparea c
) c
where cont<>0
This can also be written using a LEFT JOIN:
select c.area_id,
c.area_name,
a.cont
from apparea c
left join
(
select count(*) cont,
center_name
from applications
where claims_status=1
group by center_name
) a
on c.area_id = a.center_name
Try this query
SELECT
c.area_id,
c.area_name,
cnt
FROM
apparea c,
(select
center_name,
count(*) AS cnt
from
applications
where
claims_status=1
GROUP BY
center_name
HAVING
count(*) > 0) cont
where
c.area_id = cont.center_name;
Got the count for each center_name and then joined table to get count for each area
Use HAVING rather than where.
As it is problem with aliases.
It is not permissible to refer to a column alias in a WHERE clause, because the column
value might not yet be determined when the WHERE clause is executed.
See Section C.5.5.4, “Problems with Column Aliases”.
http://dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html
From: http://dev.mysql.com/doc/refman/5.0/en/select.html

MySQL using Inner joins on an alias of a calculated column

I have a query like so:
SELECT User.id, 10*10 as distance
FROM USERS
INNER JOIN
(
SELECT Location.user_id,
min(10 * 10) as mindistance
FROM Location
GROUP BY Location.user_id
) L ON Users.id = Location.user_id AND distance = L.mindistance
If I leave it as is, I keep getting:
Unknown column 'distance' in 'on clause'
But if I put User.distance instead of just distance, I get:
MySQL syntax error near....
Can I not use alias' this way on a calculated field? The 10 * 10 is just a simple placeholder as the calculation is much more complex.
You are trying to use a column alias in the ON clause. The MySQL documentation has this to say about this situation:
The conditional_expr used with ON is any conditional expression of the form that can be used in a WHERE clause.
And also:
Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is evaluated, the column value may not yet have been determined. For example, the following query is illegal:
That said, you can use variables to calculate the expression in the ON clause and then use the value in the column list, like this:
SELECT User.id, #dist as distance
FROM USERS
INNER JOIN
(
SELECT Location.user_id,
min(10 * 10) as mindistance
FROM Location
GROUP BY Location.user_id
) L ON Users.id = Location.user_id AND (#dist := 10*10) = L.mindistance
To avoid having to make the calculation three times in the query, you can wrap the outer calculation in a FROM subselect, which will give you access to the aliased field name (where it wasn't accessible in your original query):
SELECT a.*
FROM
(
SELECT id, 10*10 AS distance
FROM USERS
) a
INNER JOIN
(
SELECT user_id,
MIN(10 * 10) AS mindistance
FROM Location
GROUP BY user_id
) L ON a.id = L.user_id AND a.distance = L.mindistance
Here, the calculation is only done two times instead of three.
SELECT User.id, 10*10 as distance
FROM USERS
INNER JOIN
(
SELECT Location.user_id,
min(10 * 10) as mindistance
FROM Location
GROUP BY Location.user_id
) L ON User.id = Location.user_id AND L.mindistance =10*10
You can't used derived values in a query where clause - where is used to restrict records and which indexes to use - derived values can't be used by the optimizer so you need to filter the final results.
not quite sure what you're doing but try something like:
SELECT User.id, 10*10 as distance
FROM USERS
INNER JOIN
(
SELECT Location.user_id,
min(10 * 10) as mindistance
FROM Location
GROUP BY Location.user_id
) L ON User.id = Location.user
HAVING USERS.distance = L.mindistance

Simple MySQL Join problem

Im stumped by this simple query because its one I have not tried before.
Ive got a User table, User_Widget table and a Widget table.
A simple inner join shows me what widgets they have by joining user_widget.user_id = user.user_id.
How would I show the widgets in the Widget table that they dont have?
Look up WHERE NOT EXISTS with a subselect in your documentation..
Use a CROSS JOIN and a LEFT OUTER JOIN ( this is from my MS SQL experience, but the concept should hold ).
It works like this. The sub-query gets all possible combinations of user and widget.
The LEFT OUTER JOIN brings your User_Widgets associations into play.
The IS NULL part of the WHERE CLAUSE will exclude widgets that the user does have, giving you only the ones that don't.
SELECT allpossible.User_ID, allpossible.Widget_ID FROM
(
SELECT User_ID, Widget_ID FROM
Users
CROSS JOIN
Widgets
) allpossible
LEFT OUTER JOIN
User_Widgets uw
ON
allpossible.User_ID = uw.User_ID
AND allpossible.Widget_ID = uw.Widget_ID
WHERE
uw.UserID IS NULL
SELECT * FROM widgets WHERE id NOT IN
(
SELECT widget_id FROM user_widgets WHERE user_id = 1
)
(where 1 is the id of the user you're interested in)
This is a guess, (I haven't tried it), but try This:
Select Distinct u.*, Z.*
From User u
Left Join
(Select u.UserId, w.*
From Widget w
Where Not Exists
(Select * From User_Widget
Where userId = u.UserId
And widgetId = w.WidgetId)) Z
On Z.userId = u.UserId
Thanks to Bart Janson I got the query down to:
SELECT * FROM widgets
WHERE NOT EXISTS (
SELECT * FROM widget_user
WHERE widgets.widget_id = widget_user.widget_id
AND user_id = "ID NUMBER OF PERSON YOU WANT"
)
ORDER BY RAND()
LIMIT 10
Cheers guys
SELECT *
FROM widgets w
LEFT OUTER JOIN user_widget uw
ON w.id = uw.widget_id AND uw.user_id = 1 // or whatever user u want
WHERE uw.widget_id IS NULL;