I have an issue with some of the join statements I'm trying to use. I have two tables that need to be joined, with both featuring all of their information. They're as follows.
INSTITUTION
IName | ALocation_ID | IPicture
ADDRESS
ALocation_ID | AStreet | AZip | ...(other relevant fields)
I've been trying to use:
CREATE VIEW InstitutionView
AS SELECT * FROM INSTITUTION
LEFT JOIN ADDRESS
ON INSTITUTION.ALocation_ID=ADDRESS.ALocation_ID;
but the error I receive says something about duplicate columns. What am I doing wrong?
You will have to select the columns individually. Hopefully this helps you out a little.
CREATE VIEW InstitutionView
AS
SELECT address.id,address.iname,address.alocation_id,ipicture,institution.astreet,institution.azip
FROM INSTITUTION
LEFT JOIN ADDRESS
ON INSTITUTION.ALocation_ID=ADDRESS.ALocation_ID;
That is because ALocation_ID column is present in both the tables.
Try creating the view explicitly naming the required columns.
CREATE VIEW InstitutionView
AS SELECT Iname,INSTITUTION.ALocation_ID,IPicture,AStreet,AZip ...
FROM INSTITUTION
LEFT JOIN ADDRESS
ON INSTITUTION.ALocation_ID=ADDRESS.ALocation_ID;
Conceptually, JOIN first creates an intermediate cross-product where the columns are referenced by a table name or alias dotted by a column name from that table; then ON and WHERE filter out rows that don't match to give a second intermediate result. If a column name appears only in one table then you can leave out the table & dot to refer to the column.
MySQL 5.6 Reference Manual :: 13.2.9 SELECT Syntax
You can refer to a column as col_name, tbl_name.col_name, or db_name.tbl_name.col_name. You need not specify a tbl_name or db_name.tbl_name prefix for a column reference unless the reference would be ambiguous. See Section 9.2.1, “Identifier Qualifiers”, for examples of ambiguity that require the more explicit column reference forms.
MySQL 5.6 Reference Manual :: 9.2.1 Identifier Qualifiers
Suppose that tables t1 and t2 each contain a column c, and you retrieve c in a SELECT statement that uses both t1 and t2. In this case, c is ambiguous because it is not unique among the tables used in the statement. You must qualify it with a table name as t1.c or t2.c to indicate which table you mean.
Hence:
CREATE VIEW InstitutionView
AS SELECT IName,I.ALocation_ID,IPicture,AStreet,AZip,...
FROM INSTITUTION I
LEFT JOIN ADDRESS A
ON I.ALocation_ID=A.ALocation_ID;
You might think that if a JOIN is ON or WHERE "=" then there would be no ambiguity. However:
In the case of INNER JOIN, if there were no implicit conversions then columns compared equal would have the same value; but otherwise different values can compare "=". So you can't use just the column name to identify one value.
Moreover for LEFT JOIN, unmatched rows in the left table are extended by NULLs and are added to give a third intermediate result; so in a row a non-NULL in a column in one table can appear with a NULL in the same column of the other table. So again you can't use just the column name to identify one value.
Moreover there doesn't even need to be a test of equality of two columns in a JOIN, or even mention both of or either of columns with a shared name. So the result can have two columns (one from each input table) sharing a name where there is no expectation of equality.
Related
I have no problem joining the tables, but when I go to create a new table using the joined tables, I get an error saying that I have duplicate columns.
My code:
SELECT *
FROM field
INNER JOIN race
ON field.raceID = race.raceID;
Updated code:
CREATE TABLE fieldrace AS
SELECT f.*, r.*
FROM field f
INNER JOIN race r
ON f.raceID = r.raceID;
That's true of any select. If there are duplicated column names, you have to reference them somehow. For a .* query this would work:
SELECT f.*, r.*
FROM field f
INNER JOIN race r
ON f.raceID = r.raceID;
Individually you can also add aliases. Maybe you have an id column in both race and field tables.
SELECT f.id as field_id, r.id as race_id, ....
FROM field f
INNER JOIN race r
ON f.raceID = r.raceID;
In the query
CREATE TABLE fieldrace AS
SELECT f.*, r.*
FROM field f
INNER JOIN race r
ON f.raceID = r.raceID;
SELECT part produces two columns with the same name in the output.
Two columns with the same name presence is not allowed in table's structure, and the whole query will fail.
General solution is to list each output column in the SELECT part separately with assigning them unique aliases.
If raceID column which is used for joining is the only column whose name interferes then you may use either USING clause instead of ON clause or NATURAL JOIN instead of INNER JOIN.
CREATE TABLE fieldrace AS
SELECT f.*, r.*
FROM field f
INNER JOIN race r USING (raceID);
-- or
CREATE TABLE fieldrace AS
SELECT f.*, r.*
FROM field f
NATURAL INNER JOIN race r;
In both cases the interfered columns will be collapsed into one column which will be placed to the top of created table structure.
Of course when raceID is not the only column whose name interferes then 1st of these queries will fail due to another column duplication whereas 2nd query will use all interfered columns for joining.
You may specify complete or partial structure of newly create table. In this case the amount and relative posession of the columns in the created table won't be changed (will match SELECT output) but all another properties of the columns (datatype, nullability, etc.) and additional objects (indices, constraints, etc.) listed in the structure will be applied. The columns which are absent in the output (including generated ones) will be added into the structure with default values as the most first ones, before the columns used in USING or during NATURAL JOIN even. DEMO.
you can create "view" or name a subquery using "with"
in both cases, you can access it from anywhere in your main query
I'm trying to join two tables in MySQL, in one I have a set of IDs (of the type GTEX-14BMU-1526-SM-5TDE6) and a set of type's of tissue(SMTS), I have to select the IDs for the tissue type 'Blood' (which is another column of the same table), and then I have to take only the first two strings (GTEX-14BMU) from the ID name and make a list of the different ones.
Then I have to compare this to a second table in which I have a list of IDs that already are in the type (GTEX-14BMU) which have to meet the condition that the column sex of this same table is 2.
The expected result is a list with the IDs which are sex type 2 and have tissue type 'Blood', meaning the ones that are coinciding. I'm trying to solve this by using JOIN and all the needed conditions in the same statement, which is:
mysql> SELECT DISTINCT SUBSTRING_INDEX(g.SAMPID,'-',2) AS sampid, m.SUBJID, g.SMTS, m.SEX
-> FROM GTEX_Sample AS g
-> JOIN GTEX_Pheno AS m ON sampid=m.SUBJID
-> WHERE m.SEX=2
-> AND g.SMTS='Blood';
But I'm either getting too many results from the combination of all possibilities or I'm getting an empty set. Is there any other way to do this?
Here:
JOIN GTEX_Pheno AS m ON sampid=m.SUBJID
I suspect that your intent is to refer to the substring_index() expression that is defined in the select clause (which is aliased sampid as well). In SQL, you can't reuse an alias defined in the select clause in the same scope (with a few exceptions, such as the ORDER BY clause, or the GROUP BY clause in MySQL). So the database thinks you are referring to column sampid of the sample table. If you had given a different alias (say sampid_short) and tried to use in the ON clause of the join, you would have met a compilation error.
You need to either repeat the expression, or use a subquery:
select substring_index(g.sampid, '-', 2) as sampid, m.subjid, g.smts, m.sex
from gtex_sample as g
inner join gtex_pheno as m on substring_index(g.sampid, '-', 2) = m.subjid
where m.sex = 2 and g.smts = 'blood';
How can i use in table field values in the url
SQL Query wherein all 3 tables are joined
select * from nfojm_usedcar_variants cv
inner join nfojm_usedcar_products cp
inner join nfojm_usedcar_categories cc on
cc.id=cp.prod_cat_id and
cp.id=cv.v_prod_id and
cv.state='1' order by cv.id desc
Output as checked
Then it combines all 3 tables
nfojm_usedcar_variants
nfojm_usedcar_products
nfojm_usedcar_categories
However - all 3 tables have unique field i.e id (but with different values)
I need to pass on value of id and v_prod_id in a url
say url been :-
<a href="index.php?option=com_usedcar&pid='.$row->v_prod_id.'&vid='.$row->id.'">
But id been common field in most of the tables hence its not picking in correctly from nfojm_usedcar_variants,
Can some one help to modify a function so as to fetch in value of id and v_prod_id from the respective table of nfojm_usedcar_variants
thanks
If you have multiple tables in a join that share a common column name, and you need them, then alias them. Such as:
select a.id as aid,a.theName,b.id as bid,b.year
from tableA a
join tableB b
on b.id=a.id
then refer to those columns as aid and bid in your code that follows.
Try to avoid Ever doing a select *. Be explicit. You never know what comes flying out of a select * typically. And odds are you don't need it all. Select * is fine for messing around, but not for production code. And you can't control common column names with select *. We like to control things afterall, no?
I need to join 3 tables which have some columns with same name, like id and some foreign keys columns.
I make a select query and the results come with table names only. How to get results like "dbname"."columnname" in my queries so I can identify from which table is each columns without having to specify every columns in the query (using only an *)?
Note: I use Delphi with ZeosLib, so a solution using these tools would be OK as well. But I prefer to set this in the data base.
You have to create an alias for your field name in your query
SELECT a.ID, b.ID
FROM a
JOIN b
You need doblue quote " for field names with special characters, so change it to.
SELECT a.ID "a.ID", b.ID "b.ID"
OR
SELECT a.ID "MeaningfullName", b.ID "OtherName"
For example here I have two fields name "sent_dt" and change one to previous_time
SQL Fiddle Demo
I'm trying to do I think a simple left join between Table A and Table B. Table A contains a master identifier A and the identifier for table B. When I run the query in PHPmyadmin I get the expected results: Identifier A and Identifier B (or NULL for Identifier B when there is no record in the table B) when run on the website the results either give me both identifiers if present in both tables or neither identifiers if only found in Table A.
Can anyone give me an idea why on the website I don't get Identifier A and then NULL for identifier B?
Query
"SELECT jobindex.*, jobrequest.*, somebody.Name
FROM jobindex
LEFT JOIN jobrequest ON jobindex.idJobIndex=jobrequest.idJobIndex
JOIN somebody ON jobindex.idSomebody=somebody.idSomebody
WHERE jobindex.JobStatus NOT IN ('Closed', 'Removed') "
If you're returning the data as an associative array (in PHP), dictionary (in Python), or hash (in Perl), you'll have a problem if two tables have columns with the same name. The key just contains the column name, without the table prefix, so you can't get the column from both tables. It will pick one of the tables to use, probably the last one in the SELECT clause.
You should give the columns aliases so that you can distinguish them:
SELECT jobindex.idJobIndex AS ji_id, jobrequest.idJobIndex AS jr_id, jobindex.*, jobrequest.*, somebody.Name
Now when there's no match, $row['ji_id'] will contain the value from jobindex, $row['jr_index'] will be NULL.
Based on the suggested answer I changed the line
SELECT jobindex.*, jobrequest.*, somebody.Name
to a full select statement with each field explicitly stated
SELECT JI.idJobIndex,JI.idSomebody,JI.JobType, JI.JobReceivedStaff, JI.JobTitle, JI.JobStatus ..... JR.idJobRequest, JR.JobResponseStaff, somebody.Name
FROM jobindex as JI
This has corrected the issues I was having.