How to produce query results with automatic table aliases in MySQL? - mysql

MySQL ver 10 (MariaDB).
PHP 5.6.3
libmysql 5.1.73
It's been a while for me working with Oracle but I vaguely remember that Oracle did exactly what I'm expecting in this example. I could be mistaken or maybe MySQL just isn't doing the same thing... The example is created for this question, so if you see a syntax issue, it's related to that.
Assuming a simple schema like this:
Table COUNTRY
ID
NM
Table PROVINCE
ID
NM
CTID
I was hoping that this query:
SELECT * FROM PROVINCE P JOIN COUNTRY C ON C.ID = P.CTID
Would produce the following output:
P.ID | P.NM | P.CTID | C.ID | C.NM
Unfortunately, the output is without table aliases and columns from joined table that are in the selected table are missing from results (only one ID column in results). Like this:
ID | NM | CTID
Is there a way to get the aliased output shown above? Or is there some other way to get all five columns in the results without having to use anything like P.ID as P_ID explicitly in the query?

MySQL does not create qualified aliases like that. If you don't explicitly name aliases, you will have duplicate column names in the result, if the select-list includes columns with the same name in multiple tables.
You don't necessarily have to make aliases for all the columns, only the ones you need to differentiate.
You don't have to forego the wildcard, but you should limit the wildcard to specific tables, for which you don't need to make aliases.
SELECT C.*, P.ID AS P_ID, P.NM AS P_NM
FROM PROVINCE P JOIN COUNTRY C ON C.ID = P.CTID

Related

SQL: How do add a prefix to column names in a JOIN?

I have sql query like this
SELECT * FROM phlegm WHERE JOIN mucus ON phlegm.id = mucus.id JOIN snot ON phlegm.id = snot.id
The problem is those tables contain several columns with identical names.
For example all 3 tables contain the column named test
If I retrieve the result of the query in PHP, then I will only get one value named test ($query->get_result()->fetch_object()->test;), because the other two get overwritten.
Is there some way to edit that query so that it adds a prefix to all columns from a table? For example, column test from table mucus would be referenced in the query as mucus_test and column test from phlegm would be phlegm_test.
One way would be doing
SELECT phlegm.test as phlegm_test, mucus.test as mucus_test FROM phlegm...
But I have a LOT of columns and tables and it would make the query longer than the Great Wall of China if I had to name each field one by one.
So is there some way to add the prefix en masse?
SELECT *, phlegm.test as phlegm_test, mucus.test as mucus_test FROM phlegm...
Used aliasing to retrieve all values associated from all three tables. if you want to reference only specific column do so by using the alias_name.column_name instead of p.*, where * means all columns belonging to table that the alias is associated with( ie. p refers to phlegm).
SELECT p.*, m.*, s.*
FROM phlegm p
JOIN mucus m ON p.id = m.id
JOIN snot s ON p.id = s.id;
I removed the WHERE from your original query above, not sure why it was there.

SQL join mapping table and get back columns not rows [duplicate]

This question already has answers here:
How can I return pivot table output in MySQL?
(10 answers)
Closed 5 years ago.
since 2 days I'm trying to find a solution...
I have two tables:
-- components -- colums:
id | name | description
-- components_ingredients -- colums:
component_id | ingredient_id
=> one component can have multiple ingredients
so when I join the tables with my statement:
SELECT * FROM components c
INNER JOIN components_ingredients ci ON c.id = ci.component_id
I get back one row for every ingredient in table ci. But I want to get back only one row with the matched ingredients as additional columns like:
c.id | c.name | c.description | ci.ingredient1 | ci.ingredient2 | ci.ingredient3 ...
Is this possible and when how??
Thanks
You can try using MySQL's GROUP_CONCAT() function to create a CSV list of the ingredients for each given component.
SELECT c.id, c.name, c.description, ci.ingredients
FROM components c
INNER JOIN
(
SELECT component_id, GROUP_CONCAT(ingredient_id) AS ingredients
FROM components_ingredients
GROUP BY component_id
) ci
ON c.id = ci.component_id
Note that as #Gordon pointed out, you might be able to do without the subquery I used, but in general you might need it. The reason Gordon's query works, even according to the ANSI standard, is a given id in the components table should uniquely determine the name and description. Hence, it is OK to include those columns while using GROUP BY, because there is no ambiguity involved.
It is hard to put the ingredients in separate columns, because you don't now how many there are.
Much easier is to concatenate them together into a string in one column:
SELECT c.*, GROUP_CONCAT(ci.component_id) as component_ids
FROM components c INNER JOIN
components_ingredients ci
ON c.id = ci.component_id
GROUP BY c.id;
Note: It is generally bad practice to include columns in the SELECT that are not in the GROUP BY. However, it is okay in this case, because components.id uniquely identifies each row. This functionality is even specified as okay in the ANSI standard -- although few databases actually implement it.

Fetching value from table and passing it in url

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?

How to force mysql to show schema name along with column names in a query?

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

MySQL - Left joins without duplicate columns

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.