How to give an index hint to MySQL through Ecto - mysql

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!

Related

MySql subquery error with delete statement

I'm learning sql from these wikibooks pages and I'm trying to answer the last question "Remove all boxes from saturated warehouses" using mysql syntax. The following is what I came up with on my own mainly using previous answers from the same page.
delete from Boxes as b
where b.Warehouse in (
select w.Code
from ( select *
from Warehouses) as w
where w.Capacity < ( select count(*)
from Boxes bb inner join Warehouses ww
on bb.Warehouse = ww.Code
group by bb.Contents) ) ;
The query for this question on the site is generating
this solution doesn't work with mysql 5.0.67
ERROR 1093 (HY000): You can't specify target table 'Boxes' for update in FROM clause
That's why I'm using multiple sub queries as a way to come around this mysql message. However, I have an error in my query and therefore it's not running.
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 'as b where b.Warehouse in ( select w.Code
from ( sel' at line 1
Any idea?
I assume Boxes and Warehouse are tables, you gave Boxes an alias and used it on the Warehouse table, that's probably why it didn't work. Maybe you should try with a query after 'delete from'.
I think your warehouses table returns from than one columns (since * is used). Replace * with the column u want to get the output from.

Syntax error in MySQL Join Query

I'm getting a syntax error in MySQL query. Is MySQL and SQL server work differently? Can anyone suggest, what is wrong and where ?
select b.component, d.matter, d.bug, d.timestamp, d.os
from bugs.profiles p, ops_reports.BPR_TAG_DATA d
left join (Select * from bugs where product='test') b
on d.bug=b.bug_id
where d.tagid = 6
and timestamp between "2014-04-21" and "2014-04-24"
and login_name like 'test'
and p.userid = d.user
Error Message 24/04/2014 23:14:10 0:00:00.037 MySQL Database 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 'Select * from bugs where product='Conversions') as b
on (d.bu 1 0
You should not mix implicit and explicit joins. A simple rule: just don't use commas in the from clause.
select b.component, d.matter, d.bug, d.timestamp, d.os
from ops_reports.BPR_TAG_DATA d left join
bugs b
on b.product = 'test' and d.bug = b.bug_id left join
bugs.profiles p
on p.userid = d.user
where d.tagid = 6 and
timestamp between '2014-04-21' and '2014-04-24' and
login_name like 'test';
I also removed the subquery, moving the condition to the on clause. This makes the query more efficient. And changed the delimiters for the date constants to single quotes. Using double quotes for strings can lead to confusion.
EDIT:
All this said, the query in the question looks like it is syntactically correct. I notice that the error message does not refer to this exact query. The query has product='test') b and the error message has product='Conversions') as b. Perhaps there are other differences as well.

Joining derived tables

EDIT: I am using phpMyAdmin interface, and I have been copy/paste the codes from phpMyAdmin to here. The phpMyAdmin seems to run a "different code" as I run the following code, and generating some error message that are referring to that "different code", causing huge confusion.
** Final edit: It seems Safari is causing this: it run the "different query" when I try to run 2nd query below. Use Firefox instead, and it generate correct results. Thanks for the help and sorry for the confusion. **
I have two tables: newsFeeds, comments, where
** newsFeeds contains column PID, comments contains column FID.**
I want to join rows in two tables with matching PID = FID. My code is:
SELECT * FROM newsFeeds
INNER JOIN
(
SELECT * FROM
comments
)
ON comments.FID = newsFeeds.PID
and the error message is "#1248 - Every derived table must have its own alias".
I then add in AS newtb after ) according to other posts here. And the code is then:
SELECT * FROM newsFeeds
INNER JOIN
(
SELECT * FROM
comments
) AS newtb
ON newtb.FID = newsFeeds.PID
But another error shows up: #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 'INNER JOIN( SELECTFID,COUNT(*) AScount FROMcomments
LIMIT 0, 25' at line 8
I wonder how to correctly do this?
You should correct this by removing the derived table:
SELECT *
FROM tb_1 INNER JOIN
tb_2
ON tb_2.FID = tb_1.PID;
MySQL has a tendency to materialize derived tables, which hurts performance.
The answer to your question, though, is to add a name after the parentheses:
SELECT *
FROM tb_1 INNER JOIN
(SELECT *
FROM tb_2
) t2
ON t2.FID = tb_1.PID;

mySql Error in Query

I have (3) tables: Professor, Comment, Course
I'm trying to get a few columns to display the professor with all the courses and all the comments they have.
My tables
SQL:
SELECT prefix, code, info, date
FROM Course, Comment
JOIN Professor ON Professor.pID = Comment.pID
AND JOIN Course ON Course.cID = Comment.cID
WHERE Comment.pID = ?
Throws error:
Syntax error or access violation: 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 'JOIN Course ON Course.cID = Comment.cID WHERE Comment.pID = '273'' at line 4
SELECT prefix, code, info, date
FROM Comment
JOIN Professor ON Professor.pID = Comment.pID
JOIN Course ON Course.cID = Comment.cID
WHERE Comment.pID = ?
Just remove the AND before the second JOIN and remove Course in the From list. You may need to change the order of the tables depending on what table data you are primarily after.
Advise that you have a read through the MySQL JOIN syntax page.
change 'AND JOIN' to just 'JOIN'
There is no AND JOIN. Please read about JOIN syntax in the manual before attempting to use it.
Additionally, you reference table Course twice.

MySQL left join subquery fail

Following query runs well in MySQL 5.x
SELECT
m_area.id, m_area.cn_areaName, m_area.de_areaName,
m_area.en_areaName,m_area.jp_areaName,t_shop.count
FROM
m_area left join
(
select t_shop.areaID, count(areaID) AS count
from t_shop
group by t_shop.areaID
) t_shop
on m_area.id = t_shop.areaID
However, when I have to run it in a 4.0.23 MySQL DB with same DB structure and data it just return following message:
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 '[
select t_shop.areaID, count(areaID) AS count
from t_s
I tried many times but still failed. Is left join to subquery not allowed in MySQL 4.x ? Then that mean I have to do it with a temp table?
Thanks in advance!
Subqueries were quite not well supported with MySQL 4.0 : it became possible to use them (at least, in some real, useful way) with MySQL 4.1 -- and MySQL 4.0 is really old, now...
See for instance this page of the MySQL manual : 12.2.8. Subquery Syntax (quoting, emphasis mine) :
Starting with MySQL 4.1, all subquery forms and operations that the
SQL standard requires are supported,
as well as a few features that are
MySQL-specific.
With MySQL versions prior to 4.1, it
was necessary to work around or
avoid the use of subqueries. In
many cases, subqueries can
successfully be rewritten using joins
and other methods. See Section
12.2.8.11, “Rewriting Subqueries as Joins for Earlier MySQL Versions”.
take out ", count(areaID) AS count"
The multiple columns in the subquery is messing up the join.
A temp table should work fine ....
Have fun!
Only thing I could think of is adding the tablename to your areaID in the subquery or renaming the reserved word count to cnt.
SELECT m_area.id
, m_area.cn_areaName
, m_area.de_areaName
, m_area.en_areaName
,m_area.jp_areaName
,t_shop.cnt
FROM m_area
left join (
select t_shop.areaID
, count(t_shop.areaID) AS cnt
from t_shop
group by t_shop.areaID
) t_shop on m_area.id = t_shop.areaID