Finding the error on SQL query when learning Inner join multitable - mysql

I am learning SQL and when doing some exercises this question showed up to me.
In matter of Multi-table consults I see sometimes that I can use Where clause instead of inner join, but Í try to use join because is the topic im trying to learn now. In this example I wrote this:
select p.nombre from pokemon p join pokemon_forma_evolucion pfe
on p.numero_pokedex = pfe.numero_pokedex
join forma_evolucion fo
on pfe.id_forma_evolucion = fo.id_forma_evolucion
join tipo_evolucion t
on t.tipo_evolucion = fo.tipo_evolucion
where lower(t.tipo_evolucion) = 'intercambio';
but it shows nothing. ( 0 results )
in the Exercises the correct answer by the blogger is this one and works fine showing 4 results :
select p.nombre
from pokemon p, pokemon_forma_evolucion pfe,
forma_evolucion fe, tipo_evolucion te
where p.numero_pokedex = pfe.numero_pokedex
and pfe.id_forma_evolucion = fe.id_forma_evolucion
and fe.tipo_evolucion = te.id_tipo_evolucion
and lower(te.tipo_evolucion) = 'intercambio';
I would like to know why mine is not working and how should I use the JOIN command properly.
Link of the Exercises blog with DER and access to entire "pokemon" SQL database: https://www.discoduroderoer.es/ejercicios-propuestos-y-resueltos-consultas-sql-bd-pokemon/
Thanks for the help. I am new on posting in this community but it is not the first time I used and enjoyed it.
Thanks for all

the where and join should word fine. the problem is that you are joining the table "tipo_evolucion" ON the wrong field
fild Tipo_Evolucion in table FORMA-EVOLUCION is numeric (this is the foreing key). Fild Tipo_Evolucion in table TIPO_EVOLUCION is varchar2 (this is not the primary key)
the primary key in TIPO_EVOLUCION IS id_tipo_evolucion
So your inner join should be
JOIN tipo_evolucion t ON t.id_tipo_evolucion = fo.tipo_evolucion
the query therefore is:
SELECT p.nombre
FROM pokemon p
JOIN pokemon_forma_evolucion pfe ON p.numero_pokedex = pfe.numero_pokedex
JOIN forma_evolucion fo ON pfe.id_forma_evolucion = fo.id_forma_evolucion
JOIN tipo_evolucion t ON t.id_tipo_evolucion = fo.tipo_evolucion
WHERE LOWER(t.tipo_evolucion) = 'intercambio';

Related

Are there 2 ways to JOIN a table on SELECT?

I have this discipline on Uni (over internet) and they asked to build a SELECT with JOIN.
As I have some knowledge about JOIN I tried to build the query without checking the apostille, but after I checked I saw that they are teaching somehow different.
Is it ok to do both ways or is there a "newer" version that I should always use?
The discipline is about Postgresql and I'm used to use MySQL.
Query that I'm used to:
SELECT Cliente.nome, Endereco.rua, Endereco.nro, Endereco.complement
FROM Cliente
JOIN Endereco
ON Endereco.Cod_end = Cliente.Cod_end
JOIN Pedido
ON Pedido.Cod_Cliente = Cliente.Codigo
WHERE Pedido.data = “02/01/16”;
Query that is in the apostille:
SELECT Cliente.nome, Endereco.rua, Endereco.nro, Endereco.complement
FROM Cliente, Endereco, Pedido
Where Endereco.Cod_end = Cliente.Cod_end
AND Pedido.Cod_Cliente = Cliente.Codigo
AND Pedido.data = “02/01/16”;

Using an alias to form an inner join

I have a problem which I cant figure out, and have looked on google and similar questions on here, but they are just not quite the same.
I am trying to build a MySQL Query which has two parts, the first is easy and i have done this fine, as it uses existing relationships, see...
SELECT
clientsites.SiteName,
clients.ClientName,
pafaddresses.PostTown,
pafaddresses.PostCode,
CONCAT("XXXXXXX", Replace(UPPER(pafaddresses.PostCode),' ','')) AS JouneyKeytemp,
clientsites.SiteType
FROM clientsites
INNER JOIN clients ON clientsites.ClientFk = clients.ClientPk
INNER JOIN pafaddresses ON clients.ActualPAF = pafaddresses.id
You will see from this code that an alias is generated which concats two postcodes and looks like xxxxxxxyyyyyy, this does work but for obvious reasons ive removed the actual postcodes.
What I now what to do is to bring in two fields from an unrelated table called Journeys:
SELECT
JourneyKey,
SingleDistance,
SingleTime
FROM journeys
I want to bring in SingleDistance and SingleTime, where the Journey Key = Generated Alias of JourneyKeyTemp.
I have tried adding the following:
INNER JOIN journeys ON JouneyKeytemp = journeys.JourneyKey
But I just keep getting a syntax error.
Any help would be appreciated.
Repeat the expression in join predicate:
INNER JOIN journeys
ON CONCAT("XXXXXXX", Replace(UPPER(pafaddresses.PostCode),' ','')) = journeys.JourneyKey
Or you can create a subquery:
select * from(
SELECT
clientsites.SiteName,
clients.ClientName,
pafaddresses.PostTown,
pafaddresses.PostCode,
CONCAT("XXXXXXX", Replace(UPPER(pafaddresses.PostCode),' ','')) AS JouneyKeytemp,
clientsites.SiteType
FROM clientsites
INNER JOIN clients ON clientsites.ClientFk = clients.ClientPk
INNER JOIN pafaddresses ON clients.ActualPAF = pafaddresses.id)t
INNER JOIN journeys ON t.JouneyKeytemp = journeys.JourneyKey

MySQL Join different tables

I am trying to join the following tables with the following code, but I can't join the last columns.
Table:magazine
id_mag **mag_name** id_freq
Table:frequency
id_freq **freq_name**
Table:copy
id_mag **id_copy** **copy_date** copy_price copy_page_number
Table:article
id_art **art_name** **art_page_number**
Table:copy_art
id_mag **id_copy** id_art article_page_num
I want to show a table with the following columns. The columns in the tables magazine, frequency, copy, article & copy_art that have ** ** are the ones I am interested in to be showed:
mag_name freq_name id_copy copy_date art_name art_page_number
I got the following table with this code:
SELECT * FROM magazine
JOIN frequency ON magazine.id_freq = frequency.id_freq
JOIN copy_art ON revista.id_mag=copy_art.id_mag
JOIN article ON copy_art.id_art=article.id_art
JOIN copy ON copy_art.id_copy=copy.id_copy;
Here is the translation for the name of each column that appears in the image:
id_rev = id_mag
nom_rev = mag_name
id_frec = id_freq
nom_frec = freq_name
id_rev = id_mag
id_ejem = id_copy
id_art = id_art
num_pag = article_page_num
nom_art = art_name
num_pag_art = art_page_number
fecha_ejem = copy_date
precio = copy_price
My doubt is the following:
What should I do in order to have the table with?
mag_name freq_name id_copy copy_date art_name article_page_num
Thanks a lot for your kindly support!
If you only want a few columns in the output, then you have to list which columns you do want. The key structure of the data is unclear (meaning it isn't clear which columns are the primary keys of each table); you have the id_mag and id_copy columns both appearing in copy and copy_art and it isn't entirely clear whether they're a composite key or id_copy is sufficient. Given that we don't have that information, we'll have to take your SELECT statement and its joins as gospel, but I'm not convinced that's correct.
You wrote:
SELECT *
FROM magazine
JOIN frequency ON magazine.id_freq = frequency.id_freq
JOIN copy_art ON revista.id_mag=copy_art.id_mag
JOIN article ON copy_art.id_art=article.id_art
JOIN copy ON copy_art.id_copy=copy.id_copy;
This collects all the columns from all the tables mentioned, which is wasteful. So, you need to specify which columns you do want:
SELECT m.mag_name, f.freq_name, c.id_copy, c.copy_date, a.art_name, a.art_page_number
FROM magazine AS m
JOIN frequency AS f ON m.id_freq = f.id_freq
JOIN copy_art AS y ON m.id_mag = y.id_mag
JOIN article AS a ON y.id_art = a.id_art
JOIN copy AS c ON y.id_copy = c.id_copy;
I'm not entirely sure that you need the copy_art table in the query, but I'm assuming you know your data better than I do.
You have to make sure that one of the first tables has got a foreign key for the articulo table to join that as well.
If you add that (For example in the revista table), you can make a JOIN over all tables with something like this:
SELECT * FROM revista
JOIN frecuencia ON revista.id_frec = frecuencia.id_frec
JOIN ejemplar ON revista.id_rev = ejemplar.id_rev
JOIN articulo ON revista.id_art = articulo.id_art;
See this fiddle for an example (I query * here, you can change that to just the columns that you need).

Convert MS SQL Server Query in MYSQL QUERY

I have written a Query,
SELECT dbo.boat.boatno, dbo.boat.boattype, dbo.staff.staffFirstName, dbo.staff.staffLastName,
dbo.branch.branchAddress
FROM dbo.boat INNER JOIN
dbo.BoatOwner ON dbo.boat.OwnerNo = dbo.BoatOwner.OwnerNo INNER JOIN
dbo.branch ON dbo.boat.BranchNo = dbo.branch.branchno INNER JOIN
dbo.staff ON dbo.branch.branchno = dbo.staff.Branchno
WHERE (dbo.branch.branchAddress LIKE '%LONDON%')
But It doesn't work in MYSQL QUERY
How can i convert this into MYSQL QUERY?
You need to know correct table names for MySQL. Assuming a similar structure, I might try:
SELECT b.boatno, b.boattype, s.staffFirstName, s.staffLastName, br.branchAddress
FROM boat b INNER JOIN
BoatOwner bo
ON b.OwnerNo = bo.OwnerNo INNER JOIN
branch br
ON b.BranchNo = br.branchno INNER JOIN
staff s
ON br.branchno = s.Branchno
WHERE br.branchAddress LIKE '%LONDON%';
MySQL does not use the three-part naming that SQL Server does. There is no "schema" in the middle of the name. The additional periods in the column names are probably one source of confusion. Using table aliases should work in both databases and makes the code more readable.
Just a guess from general principles, but perhaps the simpler
SELECT A.boatno, A.boattype, D.staffFirstName, D.staffLastName, C.branchAddress
FROM dbo.boat A, dbo.BoatOwner B, dbo.branch C, dbo.staff D
WHERE B.OwnerNo = A.OwnerNo AND C.branchno = A.BranchNo AND D.Branchno = C.branchno
AND C.branchAddress LIKE '%LONDON%'
may work.
To begin, make sure also that you can SELECT from dbo.boat, dbo.BoatOwner, dbo.branch and dbo.staff using your PHPmyAdmin environment. Sometimes the simple things trip us up...
SELECT b.boatno, b.boattype, s.staffFirstName, s.staffLastName, br.branchAddress
FROM boat b INNER JOIN
BoatOwner bo
ON b.OwnerNo = bo.OwnerNo INNER JOIN
branch br
ON b.BranchNo = br.branchno INNER JOIN
staff s
ON br.branchno = s.Branchno
WHERE br.branchAddress LIKE '%LONDON%';
GROUP BY b.boatno
Isn't that enought?

Taking one column from MySQL joined tables

I have a query in MySQL and I am making a crystal report by using this.
Now inside the query i have a column called scan_mode and it is coming from gfi_transaction table. This scan_mode I am using in report to suppress some sections. But some times this value is coming null for some transaction ids.
So now I want to take this scan_mode as separate query so that it will work.
Can any one please help how I can modify the below query to take only scan_mode column.
SELECT
cc.cost_center_code AS cccde,
cc.name AS ccnme,gf.scan_mode,
cc.cost_center_id AS ccid,
site.name AS siteme,
crncy.currency_locale AS currency_locale,
cntry.language AS LANGUAGE,
cntry.country_name AS cntrynm,
crncy.decimal_digits AS rnd,
gf.transaction_no AS Serial_No,
brnd.name AS brand_name,
rsn.description AS reason,
gf.comment AS COMMENT,
ts.status_description AS STATUS,
DATE_FORMAT(gf.created_date,'%d/%m/%Y') AS created_date,
gf.created_by AS created_by,
IFNULL(gf.approval_no,'Not authorized') AS Trans_no,
gf.approved_date AS approval_dt,
gf.approved_by AS approved_by,gf.status AS status1,
IFNULL(loc.cost_center_code,cc.cost_center_code) AS cur_location,
gf.document_ref_no,gf.document_ref_type,
,DATE_FORMAT(document_ref_date1,'%d/%m/%Y')) AS invoice_no
FROM
gfi_transaction gf
INNER JOIN gfi_instruction gfn ON (gf.transaction_id=gfn.transaction_id)
INNER JOIN gfi_document_instruction doc ON (gf.ref_transaction_no = doc.document_instruction_id)
INNER JOIN reason rsn ON (gf.reason_id = rsn.reason_id)
INNER JOIN gfi_status ts ON (gf.status = ts.gfi_status_id)
INNER JOIN transaction_type tt ON (gf.transaction_type_id = tt.transaction_type_id)
INNER JOIN brand brnd ON(gf.brand_id=brnd.brand_id)
-- cc details
INNER JOIN cost_center cc ON (brnd.parent_brand = cc.brand_id OR gf.brand_id = cc.brand_id)
INNER JOIN site site ON(cc.site_id = site.site_id)
INNER JOIN country cntry ON (site.country_id = cntry.country_id)
INNER JOIN currency crncy ON (cntry.currency_id=crncy.currency_id)
LEFT OUTER JOIN alshaya_location_details loc ON
(gf.brand_id = loc.brand_id AND loc.cost_center_id = gf.cost_centre_id)
LEFT OUTER JOIN alshaya_location_details locto ON
(locto.cost_center_id = gf.from_cost_center_id)
WHERE
gf.transaction_id='{?TransID}'
AND rsn.transaction_type_id IN (10,11,14)
wow, that's a big query. I ran across a similar problem in a query i was building and found the if syntax to be a solution to my problem. This was also answered in this question: MYSQL SELECT WITHIN IF Statement
$psdb->query = "SELECT count, s.classid,
if (k.sic != k.siccode, k.siccode, s.siccode) as siccode,
if (k.sic != k.siccode, k.sicdesc, s.sicdesc) as sicdesc,
if (k.sic != k.siccode, k.sicslug, s.sicslug) as sicslug
FROM ...
It looks like scan_mode column comes from "gfi_transaction" table which seems to be primary table in your query. If you get null for this column then it means your table itself have NULL value for this column. Taking that separately in a query wont solve your problem. Try replacing null with a default value and handle it in code. You can add default value instead of NULL by using ifnull(scan_mode, 'default')