I am new in programming. A have a query which sometimes works but sometimes doesn't works at all. I mean if the result is not only a row it become too slow. If the result is several hundred rows it doesn't works at all. I know it's not the best to use 'like' in the query but I have no other options (or I just don't know).
Please help me to optimize my query.
I should run this query with different "where" options (the first part would be always the same). Shall I store the first part in a function? Does it make the query faster?
SELECT a.*,
group_concat(DISTINCT concat(' ', b.name)),
group_concat(DISTINCT concat(' ', e.name)),
group_concat(DISTINCT concat(' ', g.name))
FROM t1 a
LEFT JOIN t2 c
INNER JOIN t3 b ON c.id = b.id ON a.id = c.id
LEFT JOIN t4 d
INNER JOIN t5 e ON e.code = d.code ON a.id = d.id
LEFT JOIN t6 f
INNER JOIN t7 g ON g.code = f.code ON a.id = f.id
WHERE a.x LIKE '%5%'
GROUP BY a.id;
Thank you in advance!
A join without condition is a cross join. In your query there are three such joins: t2, t4, t6 tables. A CROSS JOIN is a JOIN operation that produces the Cartesian product of two tables. It will produce rows which combine each row from the first table with each row from the second table. The performance is poor because cross join produces too many rows. See documentation: https://www.w3resource.com/sql/joins/cross-join.php
if a.x is a varchar field use something like
Full-Text Index
I 'm not sure if mysql has it but give it a try
This is what I use in SQL Server
Related
I have a simple query:
SELECT t1.tbl,
t1.slug
FROM t1
WHERE tags = '%".$tag."%'
However, I need to augment my results with the data from other tables (t2, t3, t4 and t5).
For example, if t1.tbl = 't2' I need to add from:
SELECT t2.title
FROM t2
WHERE t2.county = '".$county."'
which I could join like this:
LEFT JOIN ON (t1.rid = t2.id)
In each of there tables I'll filter by $county even though the column is named differently.
I've tried something like this:
SELECT t1.tbl,
t1.slug
FROM t1 A
LEFT JOIN (
SELECT title
FROM t2 B
WHERE A.tbl = 't2'
) ON (A.rid = B.id)
WHERE A.tags = '%".$tag."%'
Is there a way to combine all there into a single query?
SELECT A.tbl,
A.slug,
COALESCE(B.title, C.title) AS title
FROM t1 A
LEFT JOIN t2 B
ON A.tbl = 't2' AND A.rid = B.id AND B.county = ?
LEFT JOIN t3 C
ON A.tbl = 't3' AND A.rid = C.id AND C.region = ?
WHERE A.tags LIKE ?
AND COALESCE(B.id, C.id) IS NOT NULL;
The last condition is to return only rows from A that have a match among one of the joined tables.
I think that's enough to see the pattern, so you can add more tables.
I urge you to learn to use query parameters instead of concatenating variables directly into your SQL string. It's easier to write the code and more secure from SQL injection vulnerabilities if you use query parameters.
I want to join 2 tables with many to many relationships.
I already tried the Left, Right and other Joining of table methods but I can't get my expected result.
This is a sample:
tblcharge
tblgrades
This is my code
SELECT a.student_id,
a.description,
b.subject_id FROM tblcharge AS a
LEFT JOIN tblgrades AS b ON
(a.student_id=b.student_id) AND b.school_yr_id=18 AND b.semester_id=1
WHERE a.sy_id=18 AND a.sem_id=1 AND a.student_id='15-3060'
Output
What i want is like this
This looks like a left join to me:
select t1.id, t1.item, t2.item
from t1 left join
t2
on t1.id = t2.id and t1.item = t2.item;
SELECT grd.STUDENT_ID,chrg.DESCRIPTION, grd.SUBJECT_ID
FROM TBLGRADES grd CROSS JOIN TBLCHARGE chrg
WHERE grd.STUDENT_ID = chrg.STUDENT_ID
I have a query like this:
SELECT a.number, a.name, b.name1 FROM a,b
WHERE a.number NOT IN (SELECT number FROM c)
AND a.name = b.name1
This query takes a very long time to run. I think it is because of the subquery.
Is it possible to avoid using subquery in this case?
You can use this code as an alternative to get your results.
SELECT a.number, a.name, b.name1
FROM a
JOIN b ON a.name = b.name1
LEFT JOIN c ON a.number = c.number
WHERE c.number is NULL;
You must however check to make sure you have properly defined indexes on your table unless the query will do full table scans on each execution. This will not be noticeable when the data in your table is small, it will start to get slower as your table grows.
You can do an explain on the query to check its execution plan, and optimise accordingly.
EXPLAIN SELECT a.number, a.name, b.name1
FROM a
JOIN b ON a.name = b.name1
LEFT JOIN c ON a.number = c.number
WHERE c.number is NULL;
Try using join:
SELECT a.number, a.name, b.name1
FROM a join b on a.name = b.name1
left join c on a.number = c.number
WHERE c.number is null
For example, I execute this MySQL statement
SELECT table1.a, table2.b, table3.c FROM table1, table2, table3
WHERE
a.id = b.id
AND
a.id = c.id
When there are some rows where a.id = b.id but no rows where a.id = c.id in this case,
no rows are shown in the result.
So, I want to make SQL to ignore a.id = c.id statement and show only rows that a.id = b.id is true.
Could you tell me how to do this? Thank you.
You should always use explicit join syntax. A simple rule: never use commas in the from clause.
Your query, properly written, is:
SELECT table1.a, table2.b, table3.c
FROM table1 a join
table2 b
on a.id = b.id join
table3 c
on a.id = c.id;
I notice the table aliases you use (a', b, and c) are the same as the column names. This is unusual, but allowed.
If you want to keep the records from a, then switch to left join:
SELECT table1.a, table2.b, table3.c
FROM table1 a left join
table2 b
on a.id = b.id left join
table3 c
on a.id = c.id;
This syntax is superior to the implicit join because it supports outer joins. Most people also think it is also more readable and clearer.
I am trying to JOIN 3 Tables(table1, table2 & table3) in Mysql query where I want to pull the matching data from 2 tables(table1 & table2) comparing a Common Column existing in 3 tables(ie. 'PID').
When Joining these 3 tables, there is no data in table1 with the given Date('2012-12-27') then it's returning complete blank row.. Here, I want to get the matching data from the table2 matching the given Date and 'ZERO' or 'NULL' where there is no matching data in the other table ie. table1.. instead of a whole blank row.
Here is the code I was trying that returns a complete BLANK ROW..
SELECT * FROM table3 b
LEFT JOIN table1 r ON r.PID = b.PID
LEFT JOIN table2 a ON ab.PID = b.PID
WHERE b.Name ='stallion' AND r.Date = '2012-12-27' AND a.Date = '2012-12-27'
;
Use two different JOIN statement then UNION them.
The rows where there is no data in table1 (r) have r.Data = NULL and are therefore filtered away by your WHERE condition. You need to add OR r.Date IS NULL to your WHERE condition or move the condition to the ON clause:
SELECT * FROM table3 b
LEFT JOIN table1 r ON r.PID = b.PID AND r.Date = '2012-12-27'
LEFT JOIN table2 a ON a.PID = b.PID AND a.Date = '2012-12-27'
WHERE b.Name ='stallion';