MySQL: Syntaxerror when using Join? - mysql

Can you find anything wrong with this query?
SELECT * FROM requests
WHERE id = '".$id."'
LEFT JOIN request_data ON (requests.id = request_data.request_id)
GROUP BY requests.id
Been workingon it for a while but can't seem to get it right!
The database looks like this:
-requests
-id
-another column
-and a third one
-request_data
-request_id
-key
-value
EDIT: Oh right, and the error:
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 'LEFT JOIN request_data ON (requests.id = request_data.request_id) GROUP BY ' at line 3
Any ideas?

The WHERE is in the wrong place.
SELECT *
FROM requests
LEFT JOIN request_data ON (requests.id = request_data.request_id)
WHERE id = '".$id."'
You probably don't need a GROUP BY either as the WHERE ensures there will only be one id returned unless in some way you are relying on the hidden columns functionality (which you shouldn't as the results are undefined).

Related

How to resolve wrong syntax near HAVING COUNT DISTINCT?

This it the code I am trying to execute:
SELECT ID_K
FROM koncert,
programi
WHERE koncert.ID_K = programi.ID_K
GROUP BY koncert.ID_K
HAVING COUNT (DISTINCT programi.Salla) = 2
It returns this error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to
your MariaDB server version for the right syntax to use
near 'DISTINCT programi.Salla)=2 LIMIT 0, 25' at line 4.
Tried to change different things but it still won't work .
You should use the count(DISTINCT programi.Salla
) and not count (..) ..remove space between COUNT and (...
SELECT koncert.ID_K
FROM koncert
INNER JOIN programi on koncert.ID_K = programi.ID_K
GROUP BY koncert.ID_K
HAVING COUNT(DISTINCT programi.Salla) = 2
but you need also tablename for avoid ambiguity and use explicit join sintax too
First you should use qualified name for your column, when column name is same in both table
SELECT ID_K FROM
should be
SELECT programi.ID_K FROM
else, you will get ambiguous column error. Otherwise, your query looks fine except removing extra space when calling COUNT (#spencer already mentioned in comment)
Also, it is good practice to join your table using JOIN (or INNER JOIN, LEFT JOIN etc) keyword, which makes your query more clear and readable.

How to give an index hint to MySQL through Ecto

I need to hint an index to MySQL in a left join through Ecto and it's being pretty difficult.
The closest I've got is this:
query = from(s in Dossier.School,
left_join: sc in fragment("subscription_coordinators use index (subscription_coordinators_school_products_idx)"),
on: fragment("school_id = ?", 1)
and fragment("product in ('reading', 'maths')")
and is_nil(sc.deleted_at),
select: s,
where: s.id == 1
)
# Ecto.Adapters.SQL.to_sql(:all, Dossier.Repo, query)
query |> Dossier.Repo.all
in IEx that compiles and generates SQL fine:
SELECT s0.`id`, s0.`name`, s0.`school_code`, s0.`deleted_at`, s0.`district_id`
FROM `schools` AS s0
LEFT OUTER JOIN (subscription_coordinators use index (subscription_coordinators_school_products_idx)) AS f1 ON (school_id = 1 AND product in ('reading', 'maths')) AND f1.`deleted_at` IS NULL WHERE (s0.`id` = 1)
but obviously the position of the table alias is wrong so actually running the query produces:
** (Mariaex.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 'f1 ON (school_id = 1 AND product in ('reading', 'maths')) AND f1.`deleted_at` IS' at line 1
(ecto) lib/ecto/adapters/sql.ex:436: Ecto.Adapters.SQL.execute_and_cache/7
(ecto) lib/ecto/repo/queryable.ex:130: Ecto.Repo.Queryable.execute/5
(ecto) lib/ecto/repo/queryable.ex:35: Ecto.Repo.Queryable.all/4
The full query is much bigger with nearly a dozen left joins (though this is the only one that needs a hint) and all in Ecto. I want to keep the fragment as small as possible if it can be done.
This is only a temporary solution though. We'll ANALYZE TABLES soon so it's unnecessary.
It is not supported currently. Please open up an issue in the Ecto repository and we will discuss it. Thank you!

mysql statement returns syntax error

For some reason I get the following error when running the code below:
#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 postcodes_demographics INNER JOIN latlon1 on postcodes_demographics.postc' at line 3
I don't understand what I'm doing wrong, thanks for any suggestions!
INSERT INTO pslatlong
SELECT postcodes_demographics.*, latlon1.*,
FROM postcodes_demographics
INNER JOIN latlon1
on postcodes_demographics.postcode = latlon1.postcodens;
You have an errant comma:
SELECT postcodes_demographics.*, latlon1.*, <--- HERE
Remove it.
I would be very surprised if merely removing the comma fixes the problem. When using insert, you should get in the habit of listing all the columns explicitly:
INSERT INTO pslatlong(col1, col2, . . . )
SELECT d.col1, l.col2, . . .
FROM postcodes_demographics d INNER JOIN
latlon1 ll
on d.postcode = ll.postcodens;
You need to do this to be sure that the right column is assigned the right value, to allow auto incrementing columns to be auto-incremented, and to prevent problems based on the number of columns.
This may works:
INSERT INTO pslatlong
SELECT postcodes_demographics.*, latlon1.*
FROM postcodes_demographics
INNER JOIN latlon1
on postcodes_demographics.postcode = latlon1.postcodens;

Rails find_by_sql and parameter for id

Qucik question, why is the 2nd line of code working and the first not?
Detail.find_by_sql("SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = ?", self.id)
Detail.find_by_sql("SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = '#{self.id}'")
first line gives me MySQL error, looks like it doesn't pass the parameter to the SQL
Mysql2::Error: 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 '?' at line 1: SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = ?
You have to use it like this :
Detail.find_by_sql(["SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = ?", self.id])
Wanted to comment on AshwinKumarS's answer, but seems I have no rep points, so I have to post here. He gave the right answer, but with no explanation. Yes, find_by_sql only accepts a single array as its parameter. If you look at the API doc, it gives a wrong method signature (showing the sql parameter as independent of the bind array, but the samples below it are correct). I just wasted, like, an hour, trying to debug a problem caused by this (and of course it shows up as a MySQL syntax error rather than a Rails error - very confusing and frustrating!) Because this method only accepts a single, flat array, if you have many, or a variable number of parameters to pass, do it like this:
Detail.find_by_sql(["SELECT * FROM blah WHERE column1 = ? AND column2 in (?,?,?)", array_of_values].flatten)
find_by_sql supports only sql queries while you are using rails syntax
You should write your query in sql syntax like this:
Detail.find_by_sql("SELECT * FROM details INNER JOIN players ON players.id = details.player_id WHERE players.team_id = #{self.id}")
Or, you can also find it in rails syntax:
Detail.joins(:player).where("players.team_id = ?", self.id)

Can I count number of rows in joined table?

Like this:
SELECT s.*, count( logs.* ) as ssh_count
FROM servers s
LEFT JOIN logs ON s.ip_address = logs.server_ip
But I get an error with that query:
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 ssh_count FROM servers s LEFT JOIN logs ON s.ip_address = logs.server_ip LIMIT' at line 1
I think that's because you can't address a table in the count function.
I can do this using a subquery, but that will likely slowly down the query.
What is a better way of doing this?
You can adress a table column, but you can't address table.*, you can do this for example:
SELECT s.*, count( logs.server_ip ) as ssh_count
FROM servers s
LEFT JOIN logs ON s.ip_address = logs.server_ip