Using an alias to form an inner join - mysql

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

Related

Why are my records blank in my Access query?

I'm trying to run this query:
SELECT tbl_G_ov_wta.PK_G, qry_performPrepElo_wta.PK_G,
qry_performPrepElo_wta.ID1_ocStake
FROM tbl_G_ov_wta
INNER JOIN qry_performPrepElo_wta
ON tbl_G_ov_wta.PK_G = qry_performPrepElo_wta.PK_G
For some reason it won't pull through the values of qry_performPrepElo_wta.ID1_ocStake. Worth mentioning that PK_G is a common primary key. In playing around with this I've found that adding in criteria as follows fixes the issue:
SELECT tbl_G_ov_wta.PK_G, qry_performPrepElo_wta.PK_G,
qry_performPrepElo_wta.ID1_ocStake
FROM tbl_G_ov_wta
INNER JOIN qry_performPrepElo_wta
ON tbl_G_ov_wta.PK_G = qry_performPrepElo_wta.PK_G
WHERE (((tbl_G_ov_wta.PK_G) Between 1 And 1000000));
Any ideas on why this might be?

Using results from a query within the same query

I have a rather big SQL statement that I am working with in MS Access 2010. Here it goes:
SELECT
W.ID AS wid,
W.wpt_ty AS ty,
W.wpt_num AS num,
W.wpt_nxt AS nxt,
W.latdeg AS lat,
W.londeg AS lon,
W.alt AS alt,
W.mission_id AS mid,
W.ctg1 AS ctg1,
W.ctg2 AS ctg2,
W.ctg3 AS ctg3,
W.ctg4 AS ctg4,
W.wpt_index AS indx,
W.vel AS vel,
W.tu AS tu,
R.route_num AS rnum,
R.AC_num AS ac,
R.route_type AS rtype,
R.LastUpdatedOn AS d8,
R.LastUpdatedBy AS auth,
R.flight_wpt_count AS wfcount,
M.mission_name AS msnName,
V.Description AS vstatus,
R.disallowed_reason_id AS did,
CW.wpt_num AS c1num,
CR.matching_route_id AS c1mrid,
CW.wpt_index AS c1indx,
CRU.runway_name AS c1rnwy,
CR.route_num AS c1rnum
FROM Validation AS V
(RIGHT JOIN Runways AS CRU
INNER JOIN (Routes CR
INNER JOIN Waypoints CW ON CR.ID = CW.route_id)
ON Runways.ID = Routes.runway_id
INNER JOIN ((Missions as M
INNER JOIN Routes AS R ON M.ID = R.mission_id)
INNER JOIN Waypoints AS W ON (R.ID = W.route_id)
AND (M.ID = W.mission_id)) ON
V.ID = R.validated
WHERE (((R.matching_route_id)=307543) AND ((R.validated) <> 0 ))
AND (((CW.mission_id)=mid) AND ((CW.wpt_num) = (ctg1))))
If you look at the bottom, you can see am I referencing the values ctg1 and mid on a Right Join while the Inner Joins reference other literal values. Eventually I will want to do the same for ctg2, ctg3, and ctg4
Right now I am running these as 2 separate queries but finding it to be way too slow. If I can join combine the queries (sort of like how I am showing here) it could speed things up greatly. But I am at a loss for how to:
Using select values earlier in said query from the Inner/Left join and push them into values needed on the Right join.
I may be using joins incorrectly, but I thought they had to do with combining data from possible the same tables, just on different pivot points.
How to use the MS Access GUI to help write a query like this.
I know this is for MS Access but I am tagging for MySQL just in case there are similar queries there which can be ported to MS Access?
Have you tried using UNION for this?
It would allow you to execute this query (As two queries, which you mentioned as a possibility), and join the results for your output.
Be warned, it will eat up (only show one of) your duplicates in the results set.
I also suggest reading up on the different types of joins for your own benefit, in the following answer:
MYSQL Joins

Why can't I exclude this row based on a condition?

http://sqlfiddle.com/#!3/3ec1f/119
Here's my fiddle...I want the result to look like this but the query I'm using doesn't do that:
My problem with the query is that I can't seem to exclude "The Kingdom of the Crystal Skull" using the exclusion_flag condition. I also don't know why it seems that Contract 3 (Raiders of the Lost Arc) is not showing up either. I have been toiling with this for hours and have no idea what the problem is. I tried looking into subqueries, but I'm not sure that's the solution...
There's a couple of questions/issues there so I'll try to address them individually.
1) You can't exclude "The Kingdom of the Crystal Skull" using the exclusion_flag because contract_sid 7 and 8 both refer to product_list_sid 3 which includes "The Kingdom of the Crystal Skull" - you would need to create a separate product_list_sid if you wanted a contract which excluded it.
2) "Raiders of the Lost Arc" (contract_sid 3) isn't showing up because it's a "single product" contract, and your query only joins from scope to product_list_join using product_list_id - contract_sid 3 is in the product_sid column so you need a separate join to cater for contracts that use product_sid instead of product_list_sid (I assume that a contract can't use both). This is a pretty dodgy schema design but here's a query that solves that issue. Notice the use of LEFT OUTER JOIN to indicate that the table being joined to might not contain any rows (for example when scope.product_list_sid is NULL but scope.product_sid is not).
SELECT s.contract_sid,
c.contract_description,
ISNULL(p.product_description, p2.product_description) AS product_description
FROM scope s
JOIN contracts c ON (c.contract_sid = s.contract_sid)
LEFT OUTER JOIN
product_list_join plj ON (plj.product_list_sid = s.product_list_sid)
LEFT OUTER JOIN
products p ON (p.product_sid = plj.product_sid)
LEFT OUTER JOIN
products p2 ON (p2.product_sid = s.product_sid)
WHERE s.exclusion_flag = 'N'
ORDER BY s.contract_sid;
Here's the SQLFiddle for my solution: http://sqlfiddle.com/#!3/fc62e/10
Edit: After posting this I realised what you're actually trying to do - the scope table not only provides the details of contracts but also provides specific products to exclude from contracts. Again, this is bad schema design and there should be a separate scope_exclusions table or something, but here's a query that does that and excludes "The Kingdom of the Crystal Skull" as requested:
SELECT inner_query.contract_description,
inner_query.product_description
FROM (
SELECT s.contract_sid,
c.contract_description,
ISNULL(p.product_sid, p2.product_sid) AS product_sid,
ISNULL(p.product_description, p2.product_description) AS product_description
FROM scope s
JOIN contracts c ON (c.contract_sid = s.contract_sid)
LEFT OUTER JOIN
product_list_join plj ON (plj.product_list_sid = s.product_list_sid)
LEFT OUTER JOIN
products p ON (p.product_sid = plj.product_sid)
LEFT OUTER JOIN
products p2 ON (p2.product_sid = s.product_sid)
WHERE s.exclusion_flag = 'N'
) inner_query
WHERE NOT EXISTS ( SELECT 1
FROM scope
WHERE exclusion_flag = 'Y'
AND contract_sid = inner_query.contract_sid
AND product_sid = inner_query.product_sid )
ORDER BY inner_query.contract_description;
SQL Fiddle: http://sqlfiddle.com/#!3/fc62e/14

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?

MYSQL get other table data in a join

I am currently running this SQL
SELECT jm_recipe.name, jm_recipe.slug
FROM jm_recipe
LEFT JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
WHERE jm_category_recipe.category_id = $cat"
This returns the desired results except that I also need to return the name of the category that the recipe I am looking for is in, to do this I tried to add the field in to my SELECT statement and also add the table into the FROM clause,
SELECT jm_recipe.name, jm_recipe.slug, jm_category_name
FROM jm_recipe, jm_category
LEFT JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
WHERE jm_category_recipe.category_id = $cat"
However this just returns no results, what am i doing wrong?
You need to join both tables:
SELECT jm_recipe.name, jm_recipe.slug, jm.category_name
FROM jm_recipe
INNER JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
INNER JOIN jm_category ON jm_recipe.recipe_id = jm_category.recipe_id
WHERE jm_category_recipe.category_id = $cat
I've changed the joins to inner joins as well. You might want to make them both LEFT joins if you have NULLs and want them in the result.
Also, you're vulnerable to SQL Injection by simply copying over $cat.
Here's some PHP specific info for you (I'm assuming you're using PHP.)