I have a set of 15 tables with a large number of columns, I know how the joins work but many of the tables have similar column names.
For example:
Select *
from table1
join table2 on table1.id = table2.id
I get back columns:
id|id|name|name
etc... I don't know which columns correspond to which tables.
What I'd like to get returned is:
table1.id|table2.id|table1.name|table2.name
I realize that I could spell out the select statement like:
select table1.id 'table1.id', table2.id 'table2.id'
But there are hundreds of column names, and dozens of tables, so this would be impractical and it seems like something that should be easy to do.
Related
I have two tables (table1, table2) in a database (both with type InnoDB). They both have a column "article". In table1 "article" is the primary index, in table2 "article" is defined as "unique". Both of those columns have data type varchar(32), also the same collation.
I am trying to get a list of all "article" values which are in table1, but NOT in table2.
table1 contains about 5000 rows, table2 contains about 3000 rows, so I should get at least 2000 "article" values as a result. My query looks like this:
SELECT article FROM table1
WHERE article NOT IN
(SELECT article FROM table2);
But this returns an empty result...
When I do it the other way around (i.e. select all "article"s from table2 which are not in table1), it works, that query returns around 700 values.
I suppose this must have to do with the different index/unique status of "article" in the two tables. But how can I modify the query to get it working?
Use a left join instead. It is faster with many values anyway:
SELECT t1.article
FROM table1 t1
LEFT JOIN table2 t2 ON t1.article = t2.article
WHERE t2.article IS NULL
I just found a second solution myself (despite the accepted answer fully working): Apparently in this situation the subquery requires a WHERE clause for the whole query to work. So I added a WHERE clause that will apply to all rows in table2 (i.e. WHERE article != ""). So the complete (working) query now looks like this:
SELECT article FROM table1
WHERE article NOT IN
(SELECT article FROM table2 WHERE article != "");
I have two tables, with 2 PKs. Table 1 has 478 records. Field 1 is a unique ID for that table only. Table 1 field 2 is a ID (shared with table 2) and 3rd field is a category field. IDs from field 2 can be repeated within a table, but I cannot have ID+category twice.
I have a 2nd table, that contains 757 records. It has a ID column and a category column (such as table1) and I want to know which records from table 1 are included on table 2. By the moment I am just checking which IDs are included in both tables (I want to clean up the database so I can use an AND query to obtain ID + category)
My SQL query does not return the desired result. When I do
SELECT DISTINCT(table1.field1) FROM table1, table2 WHERE table1.ID = table2.ID;
I get all the results that do match, but, when I do the opposite
SELECT table1.field1 FROM table1, table2 WHERE table1.ID != table2.ID;
SQL gives all the rows from table 1, when, the expected outcome would be
total rows from table 1 - IDs that do match with the ones at table 2
I've tried to invert the order in which the query is displayed as:
SELECT table1.field1 FROM table1, table2 WHERE table2.ID != table1.ID;
But then a loop occurs and I get 36000+ results which is, of course, impossible (I imagine that checking a bigger record table against a smaller one makes the small one loop over and over, and seeing that I get the full table all the time, the loop is Xtimes478, hence the 36000+ results).
I have checked this matched/unmatched query using R (just for testing) and I got 170 matches (that I can obtain in SQL) and 308 "not coincident" results (170+308=478, so I imagine it makes sense even if I am using R instead of a proper relational database system)
How can I search for unmatched IDs in a query rather than checking for matched ones and substracting from total? How to get the 308 records that do not match?
If you want values in table 1 that are not in table 2, then use not exists or something similar:
select t1.*
from table1 t1
where not exists (select 1 from table2 where t2.id = t1.id);
I have about 20 tables. These tables have only id (primary key) and description (varchar). The data is a lot reaching about 400 rows for one table.
Right now I have to get data of at least 15 tables at a time.
Right now I am calling them one by one. Which means that in one session I am giving 15 calls. This is making my process slow.
Can any one suggest any better way to get the results from the database?
I am using MySQL database and using Java Springs on server side. Will making view for all combined help me ?
The application is becoming slow because of this issue and I need a solution that will make my process faster.
It sounds like your schema isn't so great. 20 tables of id/varchar sounds like a broken EAV, which is generally considered broken to begin with. Just the same, I think a UNION query will help out. This would be the "View" to create in the database so you can just SELECT * FROM thisviewyoumade and let it worry about the hitting all the tables.
A UNION query works by having multiple SELECT stataements "Stacked" on top of one another. It's important that each SELECT statement has the same number, ordinal, and types of fields so when it stacks the results, everything matches up.
In your case, it makes sense to manufacturer an extra field so you know which table it came from. Something like the following:
SELECT 'table1' as tablename, id, col2 FROM table1
UNION ALL
SELECT 'table2', id, col2 FROM table2
UNION ALL
SELECT 'table3', id, col2 FROM table3
... and on and on
The names or aliases of the fields in the first SELECT statement are the field names that are used in the result set that is returned, so no worries about doing a bunch AS blahblahblah in subsequent SELECT statements.
The real question is whether this union query will perform faster than 15 individual calls on such a tiny tiny tiny amount of data. I think the better option would be to change your schema so this stuff is already stored in one table just like this UNION query outputs. Then you would need a single select statement against a single table. And 400x20=8000 is still a dinky little table to query.
To get a row of all descriptions into app code in a single roundtrip send a query kind of
select t1.description, ... t15.description
from t -- this should contain all needed ids
join table1 t1 on t1.id = t.t1id
...
join table1 t15 on t15.id = t.t15id
I cannot get you what you really need but here merging all those table values into single table
CREATE TABLE table_name AS (
SELECT *
FROM table1 t1
LEFT JOIN table2 t2 ON t1.ID=t2.ID AND
...
LEFT JOIN tableN tN ON tN-1.ID=tN.ID
)
Can you help me write my MySQL join query. Here is what i have so far:
SELECT * FROM table1 LEFT JOIN table2 ON table2.id IN
(table1.comma_separated_ids) WHERE table1.id = [some id]
where table1.comma_separated_ids is a VARCHAR column containing a list of comma separated IDs (integers) that relate to IDs in table2.
The above query returns only one row when it should return every row in table1.comma_separated_ids that has a matching row in table2
What I'm actually trying to do is a little more complex but it's hard to explain so I'm starting here. Any help?
In MySQL, you cannot put a comma-separated list as a single argument to in. It is treated as a string, a single string.
You can use find_in_set():
SELECT *
FROM table1 LEFT JOIN
table2
ON find_in_set(table2.id, table1.comma_separated_ids)
WHERE table1.id = XXX;
However, the bigger issue is that you are storing ids in a comma-separated list. These should be in a separate junction table, with one row per id. It is bad enough to store lists in strings; storing integer ids is even worse.
I want to select all the fields from one table and also some specific fields from other tables using LEFT JOIN. Can I use the * to select all the columns from the one table and also name the specific fields from the JOIN?
Something like this:
SELECT * , table2.a, table2.b
FROM table1
LEFT JOIN table2 ON table2.a = table1.a
WHERE ...
To get all the fields from table1 and only certain columns from table2 you would use:
SELECT table1.*, table2.column, table2.column
FROM table1
LEFT JOIN table2 ON table2.a = table1.a
WHERE ...
Syntax wise, it is correct and works. However, it is poor practice to use *. I would recommend you always specify a column list. If the columns change, your application may break. It's also always better for readability.
You specify all columns from one table with table1.* If you use * you will get all columns from all tables.
MySQL is fussy about the order of wildcarded column names - they have to be first.