MYSQL How to "Join" two Queries - mysql

I have 2 tables, one containing the UID of users with a FID (File ID) and one table containg the FID with their URI. I need to get the URI with just the UID.
My first though is to first load all of the FID with a Query and then use the fetched data to make an other query that will load the URI in the second table according to the fetched FIDs.
Since this query is going to be run a lot on this site i was wondering what would be the most efficient way to do so ? Would it be possible to join those 2 queries ?

What you want is a simple join like this:
SELECT uid, uri FROM table1, table2 WHERE table1.fid = table2.fid

SELECT
U.UID,
F.FID,
F.URI
FROM users_Table AS U
JOIN files_Table AS F
ON U.FID = F.FID
WHERE U.UID = "user_identification_number"

It's pretty easy for SQL join.
SELECT `t1`.*, `t2`.`uri`
FROM `users` t1
JOIN `files` t2 ON `t1`.`id` = `t2`.`uid`

If I understood you question correct this could be solved with a simple JOIN
SELECT UID, URI
FROM `table1` as t1, `table2` as t2
WHERE t1.FID = t2.FID;
Read more about how joins work at http://dev.mysql.com/doc/refman/5.0/en/join.html

Related

MySQL Join on LIKE statement

I need to count how many users are in each group in a database. Unfortunately the database design is not great and the users uids are stored against the group in the group table in a LONGTEXT field column name owncloudusers.
Example of owncloudusers data :
{i:0;s:36:"25C967BD-AF78-4671-88DC-FAD935FF1B26";i:1;s:36:"40D6866B-EA06-4F39-B509-8CE551CC1924";i:2;s:36:"7724C600-DE23-45C8-8BFD-326B0138E029";i:3;s:36:"D6FF37EC-11F4-471F-94C9-F3A28416CF1F";i:4;s:36:"F70C6D03-B7BA-44E4-B703-9AF3EED9BC03";}
I thought I could use a query with a LIKE on the join to compare the user's uid and look inside owncloudusers and see if there is a match.
The closest I have got is:
SELECT T1.owncloudname, count(T2.owncloud_name) AS Users
FROM oc_ldap_group_members T1
LEFT JOIN oc_ldap_user_mapping T2 ON T1.owncloudusers LIKE('%:"'||T2.owncloud_name||'";%')
GROUP BY owncloudname;
T1 table holds the groupings and who is tagged to that group
T2 table holds the users data. column owncloud_name is the users uid column
I have tried a few approaches I found on stackoverflow CONCAT on the LIKE join and LIKE('%:"'+T2.owncloud_name+'";%')
But no joy. The current statement I have returns 0 users against all the groups but I know this is not right.
I know it much but an issue on the join not sure where to go with it next.
Any assistance would be much appreciated.
I think you need a simple
SELECT T1.owncloudname, count(*) AS Users
FROM oc_ldap_group_members T1
LEFT JOIN oc_ldap_user_mapping T2 ON T1.owncloudusers LIKE '%T2.owncloud_name%'
GROUP BY owncloudname;
If you need concat try
SELECT T1.owncloudname, count(T2.owncloud_name) AS Users
FROM oc_ldap_group_members T1
LEFT JOIN oc_ldap_user_mapping T2 ON T1.owncloudusers
LIKE concat( '%',T2.owncloud_name,'%' )
GROUP BY owncloudname;
You were close, but mysql doesn't understand || as a text concatenation operator; use CONCAT() with the text parts passed as a list of values to build the LIKE operand:
SELECT T1.owncloudname, count(T2.owncloud_name) AS Users
FROM oc_ldap_group_members T1
LEFT JOIN oc_ldap_user_mapping T2
ON T1.owncloudusers LIKE CONCAT('%;', T2.owncloud_name, ';%')
GROUP BY owncloudname;
if there aint any performance issue,
could you try it with sub-query,
SELECT
T1.owncloudname,
(SELECT COUNT(*)
FROM oc_ldap_user_mapping AS T2
WHERE LOCATE(T2.owncloud_name,T1.owncloudusers)=1) AS Users
FROM
oc_ldap_group_members T1
GROUP BY
owncloudname;

MySql - Multitable - AND is not the correct choice, but what is?

I have two tables:
mytable1
UserId (int) (primary_key)
Save (blob)
mytable2
UserId (int) (primary_key)
Save (blob)
I make the following mysql command:
UPDATE mytable1 tb1, mytable2 tb2 SET tb1.Save='', tb2 .Save='' WHERE tb1.UserId=25 AND dbSv1.UserId=25
When both tables have a user with UserId = 25, then this works and Save is set to ''. However, if one table does not have a user with UserId = 25, but the other one does, then Save is not set to '' in the one that does. This is not the behaviour I want.
OR is not the thing to use, as other Saves will be set to '' which do not have an UserId of 25. So what do I need?
Your query is using the old-school comma syntax for a join operation. (There's some problems in the SQL... dbSv1 is used as a qualifier, but it doesn't appear as a table name or table alias. We're going to assume that was supposed to be tb2.
Your query is equivalent to:
UPDATE mytable1 tb1
JOIN mytable2 tb2
SET tb1.save=''
, tb2.save=''
WHERE tb1.userid=25
AND tb2.userid=25
If a matching row is not found in either tb1 or tb2, the the JOIN operation will produce an empty set. This is expected behavior.
Consider the result set returned from this query:
SELECT tb1.userid
, tb2.userid
FROM mytable1 tb1
JOIN mytable2 tb2
WHERE tb1.userid=25
AND tb2.userid=25
when there are no rows in tb2 that satisfy the predicates, the query won't return any rows.
You could use an "outer" join to make returning rows from one of the tables optional. For example, to update mytable1 even when no matching rows exist in mytable2...
UPDATE mytable1 tb1
LEFT
JOIN mytable2 tb2
ON tb2.userid=25
SET tb1.save=''
, tb2.save=''
WHERE tb1.userid=25
If there are no rows in mytable1 that have userid=25, then this won't update any rows.
MySQL doesn't support FULL OUTER JOIN. But you try something like this, using an inline view to return a row, and then performing outer joins to both mytable1 and mytable2...
UPDATE ( SELECT 25 + 0 AS userid ) i
LEFT
JOIN mytable1 tb1
ON tb1.userid = i.userid
LEFT
JOIN mytable2 tb2
ON tb2.userid = i.userid
SET tb1.save = ''
, tb2.save = ''
SQLFiddle demonstration: http://sqlfiddle.com/#!9/6f8598/1
FOLLOWUP
A "join" is a common SQL operation. You shouldn't have any trouble finding out information about what that is what it does.
The "+ 0" isn't strictly necessary. It's a convenient shorthand in MySQL to CAST to numeric. As a test, see what MySQL returns for this:
SELECT '25' + 0
, '25xyz' + 0
, 'abc' + 0
The purpose of the inline view was to return a single row. We could have written the query to hardcode the user_id two times, and ignore what's returned from the line view ....
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT 'foo' AS dontcare ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = 25
LEFT
JOIN mytable t2
ON t2.user_id = 25
My preference is to make it more clear that our intent is for both of the values to be the same. We could code where one of them is 23 and the other is 27. That's syntactically valid to do that. When we convert this to a prepared statement with bind placeholders...
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT 'foo' AS dontcare ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = ?
LEFT
JOIN mytable t2
ON t2.user_id = ?
We kind of "lose" the idea that those two values are the same. To get that hardcoded value specified only one time, I have the inline view return the value we want to "match" in the ON clause of the outer joins.
SELECT t1.user_id AS t1_user_id
, t2.user_id AS t2_user_id
FROM ( SELECT ? AS user_id ) i
LEFT
JOIN mytable1 t1
ON t1.user_id = i.user_id
LEFT
JOIN mytable t2
ON t2.user_id = i.user_id
Now my intent is more clear... I'm looking for "one" user_id value. Adding the "+ 0" indicates that whatever value gets passed in (e.g. '25', 'foo', or whatever), my statement is going to interpret that as a numeric value.
inline view
I used the term "inline view". That's just a SELECT query used in a context where we usually have a table.
e.g. if i have a table named mine, i can write a query...
SELECT m.id, m.name FROM mine m
test it and see that it returns rows, yada, yada.
I can also do this: wrap that query in parens and reference it in place of a table in another statement, like this...
SELECT t.*
FROM ( SELECT m.id, m.name FROM mine m ) t
MySQL requires that we assign an alias to that, like we can do if it were a table. We call that an inline view because it's similar to the pattern we use for a stored view. Let's look at a demonstration of doing that.
(This is just a demonstration of the pattern; there's some reasons we wouldn't want to do this.)
CREATE VIEW myview
AS
SELECT m.id, m.name FROM mine m
;
Then we can do this:
SELECT t.* FROM myview t
With the inline view we're following the same pattern, but we're bypassing a separate create view statement. (That's a DDL statement that causes an implicit commit, and creating a database object.) Bypassing that, we're effectively creating a view that exists only in the context of the statement, and doing that "inline", within the statement.
SELECT t.* FROM ( SELECT m.id, m.name FROM mine m ) t
The MySQL documentation refers to the inline view as a "derived table". If we (accidentally) forget the alias, the error we get back says something like "every derived table must have a alias". The more general term, used for databases other than MySQL is "inline view".

Select from two tables in MySQL

I have two tables with users and I want to select the users from the first table which do not exist in the second. Can you help me?
When I use the code
Select t1.user_name From t1 Inner Join t2 On t1.user_name != t2.user_name;
I get all the users many times (actually as the number of the users - 1).
Use a LEFT JOIN instead like
Select t1.user_name From t1 left join t2
On t1.user_name = t2.user_name
where t2.user_name is null;
You can use EXISTS like this
SELECT t1.user_name FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t1.id = t2.id)
This example assumes that you have some sort of ID on the tables that represents the primary key and foreign key.
Not sure how are your tables designed, but having the same info (user_name) in more than one table is considered as duplication of data. To fix this, you should read about Database normalization

problems with Join query

Hi I've got data in two tables my first table contains
first name
last name
my second table contain
userid
first name
last name
I'm trying to write a sql query to get the userid of a particular user but I'm getting empty set while executing the query. Could anyone please verify that the query I'm using is right? It seems ok to me
select users.id
FROM TABLE1 AS r
LEFT JOIN TABLE2 AS users
ON (users.firstname = r.firstname
AND users.lastname=r.lastname)
You use twice the same table (TABLE2), but in the description you state that you have two tables.
I am not sure but i think you want this:
select users.id
FROM TABLE1 AS r
INNER JOIN TABLE2 AS users
ON (users.firstname = r.firstname AND users.lastname=r.lastname)
select users.id
FROM TABLE1 AS r
INNER JOIN TABLE2 AS users
ON (lower(ltrim(rtrim(users.firstname))) = lower(ltrim(rtrim(r.firstname))) AND lower(ltrim(rtrim(users.lastname)))=lower(ltrim(rtrim(r.lastname))))

inner join for a query?

I want to do a sql query and have some problems:
I want to salect from table_1 the ID's Where parent_id is the value I have:
SELECT ID FROM table_1 WHERE parent_ID = 'x'
I want to use the ID'S I got in 1. and
SELECT FROM table_2 WHERE ID = 'The ID's from Query 1.
Simple and Execute
Select t1.`id` FROM table t1 INNER JOIN table t2 ON t1.`id`=t2.`id`
As Bainternet mentioned you can do this with a subquery
SELECT * FROM table_2 WHERE ID IN (SELECT ID FROM table_1 WHERE parent_ID = 'x')
Though your idea to use an inner join is also good (especially since MySQL can be slow when processing subqueries).
SELECT t2.* FROM table_2 as t2 INNER JOIN table_1 AS t1 ON t2.ID = t1.ID WHERE t1.parent_ID = 'x'
If that's not clear, try looking at the MySQL JOIN Syntax or the Subqueries, as Bainternet mentioned. If these examples and the MySQL docs aren't clear enough for you, consider posting more details on exactly what you're trying to do (e.g. include table structures in your question). Also while you might want this information for some WordPress related work you are doing, there's nothing in the question itself that actually ties it to WordPress. So if you have more questions that about MySQL queries in general, then you might want to consider posting them to the StackOverflow, tagged as mysql-query.