Error #1064, with Select column,* from table - mysql

Okay, just was debugging something and I found a wired error, probably it should be documented somewhere, but I search MYSQL documentation and didn't found anything. Here is the sql query, that produce 1064 error near * from table,
Select char_length(zip), zip, * from tbllocations
But this below one works fine:
Select *, char_length(zip), zip from tbllocations
Cannot we use * at end of column list? I test this query on MySQL 5.5.41 and MySql 5.0.95. I didn't notice this error before. I rewrite query to avoid special/hidden characters.
Aren't they same query except change in order of columns? Any explanation or resource to look for one.
EDIT:
Just run Select char_length(zip), zip, tbllocations.* from tbllocations and it works fine? So looks like I am hitting some bug? or anything logical, I am missing?

From MySQL docs:
A select list consisting only of a single unqualified * can be used as shorthand to select all columns from all tables:
SELECT * FROM t1 INNER JOIN t2 ... tbl_name.* can be used as a qualified shorthand to select all columns from the named table:
SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ... Use of an unqualified * with other items in the select list may produce a parse error. To
avoid this problem, use a qualified tbl_name.* reference
SELECT AVG(score), t1.* FROM t1 ...

Related

MySQL: Ordering of columns when using a wildcard with group by has odd behavior

What is the difference between these two MySQL statements?
Works:
select *, count(mycol) c from mytable group by mycol;
Doesn't work:
select count(mycol) c, * from mytable group by mycol;
The first statement works as I'd expect, while the second one gives me a syntax error. Why does the order matter?
I'm having trouble finding an answer from Google, because I'm not entirely sure if I'm asking the question correctly.
Edit:
Here's the sanitized error message. I'm using MySQL Workbench, if that's relevant.
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '* from mytable group by id' at line 1
Just alias the table and the syntax error will go away.
select count(t.id) c, t.* from mytable t group by id;
See this db fiddle.
It looks like MySQL allows bare (unqualified) * only as immediatly following SELECT. The following query also raises a syntax error :
select 1, * from mytable t;
The documentation prevents against using bare * combined with other items in the SELECT list :
A select list consisting only of a single unqualified * can be used as shorthand to select all columns from all tables.
Use of an unqualified * with other items in the select list may produce a parse error. To avoid this problem, use a qualified tbl_name.* reference.

Why MySQL error using table alias on a simple select statement?

I'm using phpmyadmin to test out some MySQL queries. I'm trying to write a larger, nested query, which is failing due to an unrecognized table alias, so I'm trying to debug smaller parts of it. However, I'm getting confusing errors when I try to use table aliases sometimes.
Can you explain why some of these queries throw errors?
SELECT * FROM table1 AS tablealias1 (works)
SELECT * FROM table1 GROUP BY userid (works)
SELECT * FROM table1 GROUP BY userid AS tablealias1 (error: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS tablealias1
LIMIT 0, 25' at line 1 )
SELECT * FROM table1 WHERE userid=1 (works)
SELECT * FROM table1 WHERE userid=1 AS tablealias1 (same error as above)
(SELECT * FROM table1 WHERE userid=1) AS tablealias1 (same error as above)
You alias things to:
rename the column display's name
give it a reference name for later use elsewhere in the query statement (whether you use it explicitly or implicitly--as long as it could be used elsehere)
If you're not doing either, an alias makes no sense. You can't alias a result set unless it's used inside a subquery, then you need an alias to reference it.
This will work:
Select * FROM (SELECT * FROM table1 WHERE userid=1) AS tablealias1
as it implies
Select tablealias1.* FROM (SELECT * FROM table1 WHERE userid=1) AS tablealias1
Alone, this is garbage:
(SELECT * FROM table1 WHERE userid=1) AS tablealias1

AS not working with COUNT(*) and UNION

So I have joined 3 queries together using UNIONs and want to count the number of lines in the result, but it's a bit weird. It actually works, and gives the correct answer, but it doesn't assign the "AS" part correctly.
SELECT COUNT(*) FROM (
(Long Select Statement)
UNION
(AnotherLong Select Statement)
UNION
(Even Longer Select Statement)
)
AS NoOfTweets";
The outcome is correct, but instead of assigning it to "NoOfTweets" it assigns it to "Count(*)". If I remove the "AS NoOfTweets" it stops working. If I remove some brackets it stops working. I'm running low on ideas after a long day! I can post the whole code if needs be but would rather not as it's quite long and I think that bit works.
Thanks in advance, Jack.
Edit: Fixed with:
SELECT COUNT(*) NoOfTweets FROM (
(Long Select Statement)
UNION
(AnotherLong Select Statement)
UNION
(Even Longer Select Statement)
)
AS NoOfTweets";
Thanks guys :)
You aren't putting it in the correct location. The beginning of your query should look like this:
SELECT COUNT(*) AS NoOfTweets
More on Column Alias
SELECT COUNT(*) NoOfTweets FROM
(Long Select Statement)
UNION
(AnotherLong Select Statement)
UNION
(Even Longer Select Statement)
or
SELECT COUNT(*) AS NoOfTweets FROM
(Long Select Statement)
UNION
(AnotherLong Select Statement)
UNION
(Even Longer Select Statement)
You have to use AS exactly after the item you are counting:
SELECT COUNT(*) AS `NoOfTweets`
FROM ( ... )
Also be careful with the " you have near the end. Or maybe it comes from a longer string.
The error is Every derived table must have its own alias which is something I didn't know, so thanks for the education :)
http://sqlfiddle.com/#!9/d30f4/4
Nice of MySQL to give an explanation - I tried with MS SQL on SQLFiddle and just got Incorrect syntax near ')'. which isn't so helpful!
So, your 'NoOfTweets' is the name given to the results column, and also to the 'derived table' which is required by the SQL engine but could be a different name ... it's not returned in the results. The point of naming a derived table is in case you wish to JOIN to other tables and reference the fields in the joins.

Avoid ambiguous condition in MySQL

I'm working on a very limited MySQL environment (all MySQL calls are passed as array parameters). The problem is I don't know how to resolve an ambiguos condition.
In this environment all MySQL calls take this form:
SELECT value1,value2,...,valueN
FROM table1,table2,...,tableN
WHERE cond1 OP cond2 OP ... OP condN
That's not a problem until you have the same column names in table1 and table2. Imagine table1 has columns {a,b,z} and table2 has column names {c,d,f,z}. I can do this:
SELECT *
FROM table1, table2
WHERE a='3' AND table1.z='5'
Perfect but, one of the limitations is that I can't use table1.z format, just z='5' that produces a collision.
So, the question is: is there any way to prevent this ambiguosity without the use of table name prefix in the condition part? (for example, it will be great if there is a way to use only part of table2 or say that table1 has priority in case of ambiguity).
There is no way to avoid a collision if you can't qualify which table "myColumn" comes from.
Your constraints seem kind of silly... You're basically asking for valid result when you assert that you cannot write valid SQL....
Perhaps instead of SELECTing from table1, you would SELECT from a nested subquery in which you aliased the column names...
For example:
if table1 and table2 both have column "myColumn"
Rather than:
SELECT
*
FROM
table1,table2
WHERE myColumn = #value -- produces collision!
Could you say:
SELECT
*
FROM
(SELECT myColumn AS foo FROM table1) newTable1,
(SELECT myColumn AS bar FROM table2) newTable2
WHERE
foo = #value
This way you're not fully qualifying the tables in the outer WHERE clause but you are re-aliasing the columns inside the subqueries (thus making them into different names for the outer query)
This seems like a roundabout exercise though
EDIT:
http://thedailywtf.com/Articles/SQL-Sentences.aspx
"MySQL sentences?"

similar functionality to SQL Server's EXCEPT operand in MySQL?

Is there an operand/function/command in MySQL similar to the EXCEPT operand in SQL Server?
EXCEPT returns any distinct values from the left query that are not also found on the right query.
This statement should give me the distinct values.
SELECT * FROM table1
EXCEPT
SELECT * FROM table2;
How can this be achieved in MySQL?
The best you could do is use a NOT EXISTS. Something like:
SELECT DISTINCT *
FROM table1
WHERE NOT EXISTS(SELECT NULL
FROM table2
WHERE table1.x = table2.x)