select *
from AllUK
where exists (select * from AllCompanies where replace(AllUK.mobile,' ','')=replace(AllCompanies.mobile,' ',''))
I need to include the columns from the AllCompanies table in to my first select. How can I do that?
select *
from AllUK a
join AllCompanies b
on a.mobile = b.mobile
exists is a boolean operation, so the clause you have above will always return all the results if there any records that can be joined accross the 2 tables. It's hard to tell what you're really trying to achieve.
Also, putting string operations on columns within exists and joins is not best practice because the compiler has to do the operation on every row & column at run time. Might be better to create a temp table to hold the replaced values and then join on that.
Related
I am completely new to database coding, and I've tried Googling but cannot seem to figure this out. I imagine there's a simple solution. I have a very large table with MemberIDs and a few other relevant variables that I want to pull records from (table1). I also have a second large table of distinct MemberIDs (table2). I want to pull rows from table 1 where the MemberID exists in table2.
Here’s how I tried to do it, and for some reason I suspect this isn’t working correctly, or there may be a much better way to do this.
proc sql;
create table tablewant as select
MemberID, var1, var2, var3
from table1
where exists (select MemberID from table2)
;
quit;
Is there anything wrong with the way I’m doing this? What's the best way to solve this when working with extremely large tables (over 100 million records)? Would doing some sort of join be better? Also, do I need to change
where exists (select MemberID from table2)
to
where exists (select MemberID from table2 where table1.MemberID = table2.MemberID)
?
You want to implement a "semi-join". You second solution is correct:
select MemberID, var1, var2, var3
from table1
where exists (
select 1 from table2 where table1.MemberID = table2.MemberID
)
Notes:
There's no need to select anything special in the subquery since it's not checking for values, but for row existence instead. For example, 1 will do, as well as *, or even null. I tend to use 1 for clarity.
The query needs to access table2 and this should be optimized specially for such large tables. You should consider adding the index below, if you haven't created it already:
create index ix1 on table2 (MemberID);
The query does not have a filtering criteria. That means that the engine will read 100 million rows and will check each one of them for the matching rows in the secondary table. This will unavoidably take a long time. Are you sure you want to read them all? Maybe you need to add a filtering condition, but I don't know your requirements in this respect.
I am new to mySQL.
I am following Mosh's tutorial to familiarize myself to SQL.
Here's my question for the following code.
SELECT *
FROM order_items
WHERE order_id = 6 AND unit_price*quantity > 30
When I looked up about SELECT *, it says: * means to return all all columns of the queried tables. Then I think SELECT * means that it grabs all tables from all schema.
My question is: Isn't it a bit inefficient and confusing to return all column provided my understanding is right? If the database become bigger and bigger, it will consume unnecessary effort to look up the keyword, so I think SELECT should specify what table it is referring to. Thanks for reading! 🥰
SELECT * does not fetch all tables from all schema. It only fetches the columns from the table you reference in your FROM clause. It only fetches the rows that match your WHERE clause.
The mistake is understandable given this statement in the MySQL documentation:
A select list consisting only of a single unqualified * can be used as shorthand to select all columns from all tables:
SELECT * FROM t1 INNER JOIN t2 ...
What they mean by "all tables" is only all tables referenced in this query. And only those in FROM or JOIN clauses. Not all tables everywhere.
SELECT * FROM table t
SELECT t.* FROM table t
I tried it and it yielded the same results, but I want to make sure because I'm refactoring a piece of code that uses the second version, and I was surprised as it is both longer to write, and less simple.
Are there any hidden stuff here?
MySQL version: 5.5.29-0ubuntu0.12.04.2 (Ubuntu)
Both statements are the same in your case.
They would be not if you join multiple tables in one query.
select *
selects all columns.
select t.*
select all columns of table t (or the table assigned the alias t)
SELECT * FROM table t and SELECT t.* FROM table t
Return the whole table
SELECT t.* FROM table as t inner join table2 as t2
will only return the fields in the "table" table while
SELECT * FROM table as t inner join table2 as t2
will return the fields of table and table2
Both the statements will give same results until it's combined with another table with some table operator as Join, Apply where you will need to uniquely identify columns( more specifically ambiguous columns ) from this table.
As a best practice you should use column names instead of using select * as it makes code more readable and front end code doesn't break in case table structure gets changed at any point of time.
The statements are identical. All you have is an alias for table "table" called "t".
SELECT * will return all columns from all tables in the query. SELECT t.* will return all columns from the table named, or aliased as, t. The same in your example because there's only one table involved.
I have a query like this :
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo WHERE group='BEST'
Basically, the table name for the main query is fetched through the subquery.
I get an error that #1054 - Unknown column 'group' in 'where clause'
When I investigate (removing the where clause), I find that the query only returns the subquery result at all times.
Subquery table adm_linkedfields has structure id | name | linktable
Currently am using MySQL with PDO but the query should be compatible with major DBs (viz. Oracle, MSSQL, PgSQL and MySQL)
Update:
The subquery should return the name of the table for the main query. In this case it will return tbl_company
The table tbl_company for the main query has this structure :
id | name | group
Thanks in advance.
Dynamic SQL doesn't work like that, what you created is an inline-view, read up on that. What's more, you can't create a dynamic sql query that will work on every db. If you have a limited number of linktables you could try using left-joins or unions to select from all tables but if you don't have a good reason you don't want that.
Just select the tablename in one query and then make another one to access the right table (by creating the query string in php).
Here is an issue:
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo
WHERE group='BEST';
You are selecting from DT which contains only one column "linktable", then you cant put any other column in where clause of outer block. Think in terms of blocks the outer select is refering a DT which contains only one column.
Your problem is similar when you try to do:
create table t1(x1 int);
select * from t1 where z1 = 7; //error
Your query is:
SELECT *
FROM (SELECT linktable
FROM adm_linkedfields
WHERE name = 'company'
) cbo
WHERE group='BEST'
First, if you are interested in cross-database compatibility, do not name columns or tables after SQL reserved words. group is a really, really bad name for a column.
Second, the from clause is returning a table containing a list of names (of tables, but that is irrelevant). There is no column called group, so that is the problem you are having.
What can you do to fix this? A naive solution would be to run the subquery, run it, and use the resulting table name in a dynamic statement to execute the query you want.
The fundamental problem is your data structure. Having multiple tables with the same structure is generally a sign of a bad design. You basically have two choices.
One. If you have control over the database structure, put all the data in a single table, linktable for instance. This would have the information for all companies, and a column for group (or whatever you rename it). This solution is compatible across all databases. If you have lots and lots of data in the tables (think tens of millions of rows), then you might think about partitioning the data for performance reasons.
Two. If you don't have control over the data, create a view that concatenates all the tables together. Something like:
create view vw_linktable as
select 'table1' as which, t.* from table1 t union all
select 'table2', t.* from table2 t
This is also compatible across all databases.
I have two large tables in a database. They both contain a column called "name". My goal is to locate rows that contain names that are in one database but not the other.
I'm guessing there will be a join statement and a where, but I cannot figure out how to use the two in tandem in order to create a successful query.
Suggestions?
SELECT * FROM TABLE_A WHERE NAME NOT IN
( SELECT NAME FROM TABLE_B )
EXISTS might be faster than IN, see Difference between EXISTS and IN in SQL?.
You can use EXISTS like this. It's useful to know both approaches since they are not exactly equal. You can swap the EXISTS quantifier for SOME, ALL or ANY. I think you can figure out what would happen :)
select * from a1 where not exists(select 1 from a2 where name=a1.name);
Note that they are not 100% equal! SQL has three-valued logic!