MySQL use select for LEFT JOIN ON - php

Just want to know can I make a such query?
SELECT
t1.id,
t1.name
FROM t1
LEFT JOIN t2 ON t2.id = (SELECT id FROM t3 WHERE t1.address LIKE 'street%' ORDER BY name ASC)
ORDER BY name DESC
This is because I want to add more complex query to the LEFT JOIN with sorting and order and some statements which depends on another table..
Thanks!
U.P.D.
SELECT * FROM t3 WHERE t1.address LIKE CONCAT(address,'%') ORDER BY LENGTH(address) DESC
Actually, I want to write this query as LEFT JOIN subquery (ORDER BY in case of LIKE does make sense!).

Theoretically you can do this.
Writing subquery in join statement will have no effect other than filtering the cartesian product of the two tables just like the where condition. But writing query this way makes no sense as we don't know the context in which you are using it.
The above query can be written in much cleaner way as follows :
SELECT
t1.id,
t1.name
FROM t1, t2
WHERE t2.id in (SELECT id FROM t3 WHERE address LIKE 'street%')
ORDER BY name DESC
It will produce the same result set as the query you provided

Related

Mysql Select All from one table, and some from another table Using Aliases

I'm posting this question because I did manage to find a similar question, but they weren't using aliases.
I have two tables - I want to grab everything from table1 and just grab the user_name and Team from table2.
My original query is grabbing everything from table2
SELECT *
FROM qabin.allqas t1
JOIN login.users t2
ON (t1.Submitter = t2.user_name)
WHERE t1.Status='Complete'
That's all well and good and works fine, but I would like to just get the user_name and the Team
To make things more interesting, they are in different databases, though it hasn't been an issue.
One is in the qabin database and the other is in the login database.
I have tried:
SELECT
qabin.allqas.* AS t1,
login.users.Team,
login.users.user_name
JOIN login.users t2
ON (t1.Submitter = t2.user_name)
WHERE t1.Status='Complete'
I need the t1 and t2 aliases because they are used elsewhere for building a larger query string.
Thanks in advance!
Why not use a subquery?
SELECT *
FROM qabin.allqas t1
JOIN (SELECT user_name, Team FROM login.users) t2
ON (t1.Submitter = t2.user_name)
WHERE t1.Status='Complete'
You cant use one alias (t1) for a set of columns. I guess what you are looking for is something like:
SELECT t1.*, t2.team, t2.user_name
FROM qabin.allqas t1
JOIN login.users t2
ON (t1.Submitter = t2.user_name)
WHERE t1.Status='Complete'
I would recommend using the real column names from t1 instead of t1.*
Try This query :
SELECT t1.*, t2.user_name, t2.Team
FROM qabin.allqas t1
JOIN login.users t2
ON t1.Submitter 1= t2.user_name
WHERE t1.Status='Complete'

MYSQL - How to sort column with ORDER BY and LIMIT and then sort those results by another column

I am currently using a MYSQL query that uses a formula to determine the similarity of rows and then order them by their difference. The query works perfect, but now I am trying to introduce LIMIT and I am have trouble. My original query is below.
SELECT t2.*, ABS(t1.v1-t2.v1)+ABS(t1.v2-t2.v2)+ABS(t1.v3-t2.v3) AS diff
FROM (SELECT * FROM tbl WHERE id=1) AS t1
JOIN tbl AS t2 ON t1.id <> t2.id
ORDER BY diff;
Now I introduced a LIMIT expression and two ORDER BY statements and it isn't working correctly. My ultimate goal is to join the tables like above, then sort the table by the id row, limit the results to 10, and then resort the table by diff ASC. Everything works fine up until the final ORDER BY of the diff, it is sorting the id column and then showing the first 10 results but not reordering the results by diff. I have been trying:
SELECT t2.*, ABS(t1.v1-t2.v1)+ABS(t1.v2-t2.v2)+ABS(t1.v3-t2.v3) AS diff
FROM (SELECT * FROM tbl WHERE id=1) AS t1
JOIN tbl AS t2 ON t1.id <> t2.id
ORDER BY id, diff LIMIT 10;
Like I said previously, the query above just keeps the rows sorted by id and limits the results to 10, but does not execute the final ORDER BY DIFF.
Thanks in advance for any help!
Is this what you want?
SELECT t.*
FROM (SELECT t2.*, ABS(t1.v1-t2.v1)+ABS(t1.v2-t2.v2)+ABS(t1.v3-t2.v3) AS diff
FROM tbl t1 JOIN
tbl t2
ON t1.id <> t2.id and t1.id = 1
ORDER BY t2.id
LIMIT 10
) t
ORDER BY diff;
You have position in your queries. I don't know what that is. Also, the subquery for t1 is unnecessary. You can just include the id in the on clause.

select left join except one column

i have select:
SELECT t1.*, t2.* from t1 left join t2 on t2.id = t1.id
when id exist or not exist in t2 I want all columns from t2 except t2.id (which can be NULL).
Is there any way do this without print out all columns names in query?
thx
No, you have to either specify all columns of interest or use a wildcard.
SELECT *
FROM t1
LEFT JOIN t2
USING (id);
That is, by the way, the reason, why it is a good idea to name the columns that you are going to use in joins the same way across the database.
If the two tables have only id as a common column, you can also use this:
SELECT *
FROM t1
NATURAL LEFT JOIN
t2
Just switch the order of requested tables
instead
SELECT t1.*, t2.* from t1 left join t2 on t2.id = t1.id
use
SELECT t2.*, t1.* from t1 left join t2 on t2.id = t1.id
The Problem Occur With "ID" Now you can do like this:
"SELECT task.*, users.emp_id,users.emp_name,users.emp_designation from task
LEFT JOIN users ON task.userid=users.id where users.sup_id='1021' AND task.date='2022-09-03'"
here i will get the task table id and all data & users table 3 column . easy and simple

Simplifying this query?

Consider this query:
SELECT table1.id,
table1.review,
table1.time,
table2.author,
table2.title
FROM
table1, table2
WHERE table1.id = table2.id
AND table1.reviewer = '{$username}'
ORDER BY table1.id
I'm using the above quite a lot around my site's code. I find that adding the table prefixes etc. before the column names can make the query very long and take up quite a lot of lines.
Is there a way to make the above query simpler/easier?
First of all, you may want to give shorter aliases to your tables. In addition, you are using the implicit join syntax which complicates the WHERE clause, and is not recommended in general. You may want to use the more modern explicit syntax instead:
SELECT t1.id, t1.review, t1.time, t2.author, t2.title
FROM table1 AS t1
JOIN table2 AS t2 ON (t2.id = t1.id)
WHERE t1.reviewer = '{$username}'
ORDER BY t1.id
Note that JOIN is a synonym for INNER JOIN, and the AS keyword is optional when defining table aliases. You can simply use ... FROM table1 t1 ... instead of ... FROM table1 AS t1 ....
You can use table aliases
SELECT t1.id, t1.review, t1.time, t2.author, t2.title
FROM
table1 AS t1, table2 AS t2
WHERE t1.id = t2.id AND t1.reviewer = '{$username}'
ORDER BY t1.id
Why dont you make a function , pass the table name and other parameter and return either values or sql query.
Your query is already simplified, i think you are worried about doing this multiple times. so better will be to create a small function in that case.
I had similar problem, which i got rid using function.
You query looks pretty optimal aside from the potential risks with your "{$username}" portion. I could very easily see some SQL injection issues if the overall query is being rendered as a straight string and not via an abstract layer of some sort.
The format I find most readable is:
SELECT
t1.id,
t1.review,
t1.time,
t2.author,
t2.title
FROM
table1 t1
JOIN table2 t2
on ( t2.id = t1.id )
WHERE
t1.reviewer = '{$username}'
ORDER BY
t1.id
It's not clear if you're "using the above code all over the site" verbatim, or the style of SQL without aliases.
If this specific piece of code is being copy/pasted, consider encapsulating this logic in a function in your PHP modules.
function GetReviewerTitles($reviewer)
{
//your select statement.
$reviewerSQL = sprintf("SELECT t1.id, t1.review, t1.time, t2.author, t2.title FROM table1 as t1 INNER JOIN table2 AS t2 ON t1.id=t2.id WHERE t1.reviewer = '%s' ORDER BY t1.id",
mysql_real_escape_string({$username}));
// Perform Query
$result = mysql_query($reviewerSQL);
//return if/when necessary
}
I suggest using a view:
CREATE VIEW ReviewInfo(id, review, time, author, title, reviewer) AS
SELECT t1.id, t1.review, t1.time,
t2.author, t2.title, t1.reviewer
FROM table1 AS t1 JOIN table2 AS t2 ON t1.id = t2.id
Now you can write your query as:
SELECT id, review, time, author, title
FROM ReviewInfo
WHERE reviewer = '{$username}'
ORDER BY id;
Note the use of abbreviations for the table names in the view definition - that is a technique you could use in your query even if you don't use a view. And the notation using an explicit JOIN operator in the FROM clause with the ON condition is preferred to the old-style FROM table1, table2.

Optimize MYSQL (3) Table Join Query

Running an EXPLAIN on some of my query tests have resulted in slow ALL joins even with indexes.
How do I make a MYSQL query with the following information more efficient?
Tables
counter: id (pk), timestamp, user_id (fk)
user: id (PK), username, website_id (fk)
website: id (pk), sitename
SELECT t2.username, t3.sitename, count(*) as views FROM counter t1
LEFT JOIN user t2 ON t2.id = t1.user_id
LEFT JOIN website t3 ON t3.id = t2.website_id
WHERE t1.id <> ""
GROUP BY t1.id
ORDER BY t1.id DESC
The result in an html table:
username, sitename, counter_views
Don't count(*), instead use count(t1.id)
Question Edit Change
With the question edit, you should put a column name in the count statement of what you want to count, e.g. count(user.id)
I believe the sql is wrong. Don't you want this:
select u.username, s.sitename, count(c.id)
from user u
join website s on u.website_id = s.id
join counter c on u.id = c.user_id
where u.id <> ""
group by u.username, s.sitename
order by u.id desc
Is your data populated yet? If these tables are empty, or very small, the optimizer may be choosing an 'all' query because the whole table is on one page. One page load from disk to get the whole table is faster than hitting a page on disk for the index, and then another page for the real data page.
Your query looks wrong. I would use something like this:
SELECT u.username, w.sitename, c.views
FROM (
SELECT user_id, COUNT(*) AS views FROM counter GROUP BY user_id
) AS c
LEFT JOIN user u ON u.id = c.user_id
LEFT JOIN website w ON w.id = u.website_id
ORDER BY c.views DESC
I would add index for counter.user_id too.

Categories