I have two table in the same database: hlstats_Events_Connects and hlstats_PlayerUniqueIds.
In the hlstats_Events_Connects I have a value I wish to get, however the ID it's related to I need to get from the data in another table, using the "uniqueId" that I have. Example:
**hlstats_Events_Connects**
playerId eventTime
----------------------
8 2013-04-05 05:44:14
**hlstats_PlayerUniqueIds**
playerId uniqueId
---------------------
8 0:0:84901
So I have the "uniqueId" as a variable, and I want to say, get the playerId of the persons uniqueId, then get the eventTime from what the playerId is. Currently I have something along the lines of the below, but can't figure out the Where clause.
SELECT c.eventTime, c.playerId, u.uniqueId, u.playerId
FROM c.hlstats_Events_Connects, u.hlstats_PlayerUniqueIds
WHERE ...?
Cheers
Looks like you are just missing the JOIN. You will join the tables on the playerId column:
SELECT c.eventTime, c.playerId, u.uniqueId, u.playerId
FROM c.hlstats_Events_Connects c
INNER JOIN u.hlstats_PlayerUniqueIds u
ON c.playerId = u.playerId
Note, I updated the query to use ANSI JOIN syntax, in this case an INNER JOIN. This is standard SQL syntax, instead of commas between the tables and the join in the WHERE
Use JOIN like this
SELECT c.eventTime, c.playerId, u.uniqueId, u.playerId
FROM c.hlstats_Events_Connects, u.hlstats_PlayerUniqueIds
WHERE c.playerId = u.playerId
You don't need to add prefixes to table names, instead those should be specified after table name, and also you can just join on playerId column (if those are large tables, I'd suggest adding an index to those columns.)
SELECT
c.eventTime, c.playerId, u.uniqueId, u.playerId
FROM
hlstats_Events_Connects c,
hlstats_PlayerUniqueIds u
WHERE
u.uniqueId = "0:0:84901" and
u.playerId = c.playerId
Related
table1 (id, name)
table2 (id, name)
Query:
SELECT name
FROM table2
-- that are not in table1 already
SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL
Q: What is happening here?
A: Conceptually, we select all rows from table1 and for each row we attempt to find a row in table2 with the same value for the name column. If there is no such row, we just leave the table2 portion of our result empty for that row. Then we constrain our selection by picking only those rows in the result where the matching row does not exist. Finally, We ignore all fields from our result except for the name column (the one we are sure that exists, from table1).
While it may not be the most performant method possible in all cases, it should work in basically every database engine ever that attempts to implement ANSI 92 SQL
You can either do
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
or
SELECT name
FROM table2
WHERE NOT EXISTS
(SELECT *
FROM table1
WHERE table1.name = table2.name)
See this question for 3 techniques to accomplish this
I don't have enough rep points to vote up froadie's answer. But I have to disagree with the comments on Kris's answer. The following answer:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
Is FAR more efficient in practice. I don't know why, but I'm running it against 800k+ records and the difference is tremendous with the advantage given to the 2nd answer posted above. Just my $0.02.
SELECT <column_list>
FROM TABLEA a
LEFTJOIN TABLEB b
ON a.Key = b.Key
WHERE b.Key IS NULL;
https://www.cloudways.com/blog/how-to-join-two-tables-mysql/
This is pure set theory which you can achieve with the minus operation.
select id, name from table1
minus
select id, name from table2
Here's what worked best for me.
SELECT *
FROM #T1
EXCEPT
SELECT a.*
FROM #T1 a
JOIN #T2 b ON a.ID = b.ID
This was more than twice as fast as any other method I tried.
Watch out for pitfalls. If the field Name in Table1 contain Nulls you are in for surprises.
Better is:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT ISNULL(name ,'')
FROM table1)
You can use EXCEPT in mssql or MINUS in oracle, they are identical according to :
http://blog.sqlauthority.com/2008/08/07/sql-server-except-clause-in-sql-server-is-similar-to-minus-clause-in-oracle/
That work sharp for me
SELECT *
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
You can use following query structure :
SELECT t1.name FROM table1 t1 JOIN table2 t2 ON t2.fk_id != t1.id;
table1 :
id
name
1
Amit
2
Sagar
table2 :
id
fk_id
email
1
1
amit#ma.com
Output:
name
Sagar
All the above queries are incredibly slow on big tables. A change of strategy is needed. Here there is the code I used for a DB of mine, you can transliterate changing the fields and table names.
This is the strategy: you create two implicit temporary tables and make a union of them.
The first temporary table comes from a selection of all the rows of the first original table the fields of which you wanna control that are NOT present in the second original table.
The second implicit temporary table contains all the rows of the two original tables that have a match on identical values of the column/field you wanna control.
The result of the union is a table that has more than one row with the same control field value in case there is a match for that value on the two original tables (one coming from the first select, the second coming from the second select) and just one row with the control column value in case of the value of the first original table not matching any value of the second original table.
You group and count. When the count is 1 there is not match and, finally, you select just the rows with the count equal to 1.
Seems not elegant, but it is orders of magnitude faster than all the above solutions.
IMPORTANT NOTE: enable the INDEX on the columns to be checked.
SELECT name, source, id
FROM
(
SELECT name, "active_ingredients" as source, active_ingredients.id as id
FROM active_ingredients
UNION ALL
SELECT active_ingredients.name as name, "UNII_database" as source, temp_active_ingredients_aliases.id as id
FROM active_ingredients
INNER JOIN temp_active_ingredients_aliases ON temp_active_ingredients_aliases.alias_name = active_ingredients.name
) tbl
GROUP BY name
HAVING count(*) = 1
ORDER BY name
See query:
SELECT * FROM Table1 WHERE
id NOT IN (SELECT
e.id
FROM
Table1 e
INNER JOIN
Table2 s ON e.id = s.id);
Conceptually would be: Fetching the matching records in subquery and then in main query fetching the records which are not in subquery.
First define alias of table like t1 and t2.
After that get record of second table.
After that match that record using where condition:
SELECT name FROM table2 as t2
WHERE NOT EXISTS (SELECT * FROM table1 as t1 WHERE t1.name = t2.name)
I'm going to repost (since I'm not cool enough yet to comment) in the correct answer....in case anyone else thought it needed better explaining.
SELECT temp_table_1.name
FROM original_table_1 temp_table_1
LEFT JOIN original_table_2 temp_table_2 ON temp_table_2.name = temp_table_1.name
WHERE temp_table_2.name IS NULL
And I've seen syntax in FROM needing commas between table names in mySQL but in sqlLite it seemed to prefer the space.
The bottom line is when you use bad variable names it leaves questions. My variables should make more sense. And someone should explain why we need a comma or no comma.
I tried all solutions above but they did not work in my case. The following query worked for me.
SELECT NAME
FROM table_1
WHERE NAME NOT IN
(SELECT a.NAME
FROM table_1 AS a
LEFT JOIN table_2 AS b
ON a.NAME = b.NAME
WHERE any further condition);
I need to change the column name while joining the MySQL query. I am explaining my code below.
select * from grc_action left join grc_users on grc_action.action_owner=grc_users.user_id
I am giving my table below.
grc_action:
id name action_owner
grc_users:
user_id name
The above is my table structure and as both has same column name i.e-name here I need to change the grc_users table column i.e-name while fetching the record. Please help me to solve this problem.
You can use AS
SELECT table1.name AS exampleName, table2.name AS otherName FROM sometable
You can also use this on tables:
SELECT vltn.id, vltn.name FROM veryLongTableName AS vltn
You dont need to type the AS, you can just do SELECT table1.name exampleName to shorten it, but it increases readbility and maintanability to write it, so I recommend doing it with AS.
You may assign different aliases to the name columns from the two different tables.
select
ga.id,
ga.name as action_name,
ga.action_owner,
gu.user_id,
gu.name as user_name
from grc_action ga
left join grc_users gu
on ga.action_owner = gu.user_id;
Note that I also used table aliases which make the query easier to read. In general, doing SELECT * is undesirable, and it is usually better to explicitly list the columns you want.
select *
from grc_action
left join grc_users on grc_action.action_owner=grc_users.user_id
changed query use this query
select *,grc_users.name as grcuser_name,grc_action.name as grcaction_name
from grc_action
left join grc_users on grc_action.action_owner=grc_users.user_id
Here geting two name like this
grcuser_name ,
grcaction_name
I am having 3 tables (c19 , c19b2, g26) in a database
I want to write a SQL Query to search and display all fields of the matched record.
I am using following query:
$query = "SELECT * FROM c19,c19b2,g26 WHERE armyno LIKE '%$searchTerm%'";
But it only works for table c19,
Data from the other 2 tables is not fetched.Each table has a field armyno
Please help me with this
Thank you.
Alright, you are not looking for a JOIN, but a UNION.
SELECT * FROM c19 WHERE armyno LIKE '%$searchTerm%'
UNION
SELECT * FROM c19b2 WHERE armyno LIKE '%$searchTerm%'
UNION
SELECT * FROM g26 WHERE armyno LIKE '%$searchTerm%'
That will let you query all three tables at the same time.
Which DB are you using? This would have worked in SQL Server. However, notice you are doing a cross join of every record to every record... usually you only want to match some records by restriction of a matching key, for example:
select
*
from a
left join b on b.somekey = a.somekey
left join c on c.someotherkey = b.someotherkey
In SQL server you can just say *, but I'm taking it that in your DB engine that didn't work, so try specifying which table. This may in some environments require aliasing as well:
select
a.*,
b.*,
c.*
from tableA as a
left join tableB as b on b.somekey = a.somekey
left join tableC as c on c.someotherkey = b.someotherkey
Generally, you should see the columns from the first table, followed by the columns from the second table, followed by columns from the third table for a given row. If you wanted to get all columns from all tables, but separately, then that would be 3 separate selects.
Lastly, if all 3 tables have "armyno" then I'd expect it to throw an ambiguous field error. In such case you'd want to specify which table's "armyno" field to filter on.
What I want to do is to query three separate tables into one row which is identified by a unique reference. I don't really have full understanding of the Join clause as it seems to require some sort of related data from each table.
I know I can go about this the long way round, but can not afford to lose even a little efficiency. Any help would be greatly appreciated.
Table Structure
package_id int(8),
client_id int(8),
unique reference varchar (40)
Each of the tables have essentially the same structure. I just need to know how to query all three, for 1 row.
If you have few tables that are sharing the same or similar definition, you can use union or union all to treat them as one. This query will return rows from each table having requested reference. I've included OriginTable info in case your code will need to refer to original table for update or something else.
select 'TableA' OriginTable,
package_id,
client_id
from TableA
where reference = ?
union all
select 'TableB' OriginTable,
package_id,
client_id
from TableB
where reference = ?
union all
select 'TableC' OriginTable,
package_id,
client_id
from TableC
where reference = ?
You might extend select list with other columns, provided that they have the same data type, or are implicitly convertible to data type from first select.
Let's say you have 3 tables :
table1, table2 and table3 with structure
package_id int(8),
client_id int(8),
unique reference varchar (40)
Let's assume that column reference is unique key.
Then you can use this:
SELECT t1.exists_row ,t2.exists_row ,t3.exists_row FROM
(
(SELECT COUNT(1) as exists_row FROM table1 t1 WHERE
t1.reference = #reference ) t1,
(SELECT COUNT(1) as exists_row FROM table1 t2 WHERE
t2.reference = #reference ) t2,
(SELECT COUNT(1) as exists_row FROM table1 t3 WHERE
t3.reference = #reference ) t3
) a
;
Replace #reference with actual value of unique key
or when you provide output of
SHOW CREATE TABLE
I can rewrite SQL with actual query
It is entirely possible to create a join between tables using a where clause. In fact this is often what I do as I find it leads to clearer information of what you are actually doing, and if you don't get the results you expect you can debug it bit by bit.
That said however a join is certainly a lot quicker to write!
Please bear in mind I'm a bi rusty on SQL so I may have missed remembered, and I'm not going to include any code as you haven't said what DBMS you are using as they all have slightly different code.
The thing to remember is that the join functions on a column with the same data (and type) within it.
It is much easier if each table has the 'joining' field named the same, then it should be a matter of
join on <nameOfField>
However if you wish to use field that have different names in the different tables you will need to list the fully qualified names. ie tableName.FieldName
If you are having trouble with natural, inner and outer, left and right, you need to think of a venn diagram with the natural being the point of commonality between the tables. If you are using only 2 tables inner and outer are equivalent to left and right (with each table being a single circle in the venn diagram) and left and right being the order of the tables in your list in the main part of your select (the first being the left and the second being the right).
When you add a third table this is where you can select any of the cross over section using these keywords.
Again however I have always found it easier to do a primary select and create a temp table, then perform my next join using this temp table (so effectively only need to use natural or left and right again). Again I find this easier to debug.
The best thing is to experiment and see what you get in return. Without a diagram of your tables this is the best I can offer.
in brief...
nested selects where field = (select from table where field = )
and temp tables
are (I think) easier to debug... but do take more writting !
David.
array_of_tables[]; // contain name of each table
foreach(array_of_tables as $val)
{
$query="select * from `$val` where $condition "; // $conditon
$result=mysqli_query($connection,$query);
$result_row[]=mysqli_fetch_assoc($result); // if only one row going to return form each table
//check resulting array ,for your row
}
SELECT * FROM table1 t1 JOIN table2 t2 ON (t2.unique = t1.unique) JOIN table3 t3 ON (t3.unique = t1.unique) WHERE t1.unique = '?';
You could use a JOIN like this, assuming all three tables have the same unique column.
select * from table1 join table2 on table1.column3=table2.column4 where ...
...
$row=mysql_fetch_assoc($result);
However, there are two columns in the new table(table1 join table2) which have the same column name, how to get the values of both respectively?
Call the columsn out specifically with an alias like
SELECT table_1.id as table_1_id, table_2.id as table_2_id
Youll have to list out all or most of the columns form at least one of the tables this way but you can get access to cols with the same name across multiple tables.
Prefix the column name in the select with its table name.
select table1.my_column, table2.my_column
from table1, table2
where table1.id = table2.t1_id
But with this method, you would have to read the columns using their returned order indexes, rather than their names. Another answer mentioned using as to name each column, so consider that if you're going to read them by name.
When there's a column name collision due to a query joining 2+ tables, you can not use *. You can use:
SELECT table_1.*,
table_2.*
FROM table_1,
table_2
If that doesn't return the list of columns you want, you will have to explicitly list every column. There's no way around - it's an all or nothing deal.
Table Aliases
...but typing out the full table name every time can be a pain, which is why you can alias tables:
SELECT t1.*,
t2.*
FROM table_1 AS t1,
table_2 t2
Either alias notation is supported. They're also required if you want to join a table to itself.
Using only the column names in a Select list that you actually need\ is always the best, but when you want everything, then, well, go ahead and use the *:
Select a.*,
b.*,
a.id as a_id,
b.id as b_id,
a.name as a_name,
b.name as b_name
from tablea a,
tableb b
...
It won't hurt to be redundant, as a.* includes a_id and a_name, but there values from the * get lost in the associative array, so just put them back in with new, unique names.