Inner join with multiple conditions on one column - mysql

I am trying to combine two tables to display.
I have one table (geofence) which holds each region id, name and associated tags. The second table is all routes and prices the user has entered from the available entries in their geofence table.
Table geofence
id
name
tags
52
texas
houston, dallas, austin
53
washington
spokane, seattle
54
oregon
portland, seaside
Table geofence_rates
id
origin_id
destination_id
price
1
52
53
1200
2
53
54
700
3
54
52
900
Desired HTML Output from combining tables
origin id
origin name
origin tags
destination id
destination name
destination tags
price
52
texas
houston, dallas, austin
53
washington
spokane, seattle
1200
53
washington
spokane, seattle
54
oregon
portland, seaside
700
54
oregon
portland, seaside
52
texas
houston, dallas, austin
900
I would like to show all routes, the price and then the associated name and tags for each of the geofence ID's.
My current sql statement gets me the routes and price but will only show the origin name and tags based off the origin id. I am not sure how to also extract the destination name and tags.
SELECT geofence_rates.origin_id, geofence_rates.destination_id,
geofence_rates.price, geofence.id, geofence.name, geofence.tags
FROM geofence_rates
INNER JOIN geofence ON geofence_rates.origin_id = geofence.id
How I can run a single statement and get both the origin and destination name and tags. I understand the bolded portion of my statement is what is causing this, but I am unsure how to create two conditions.

Your current sql statement gets you the routes and price only for the origin because you're matching the two tables on one single condition (the matching origin: geofence_rates.origin_id = geofence.id), yet at same time you're requiring information for destination too.
To solve this, you can apply two JOIN operations:
former to get information on origin
latter to get information on destination
separately.
SELECT orig.id AS origin_id,
orig.name AS origin_name,
orig.tags AS origin_tags,
dest.id AS destination_id,
dest.name AS destination_name,
dest.tags AS destination_tags,
rates.price
FROM geofence_rates rates
INNER JOIN geofence orig
ON rates.origin_id = orig.id
INNER JOIN geofence dest
ON rates.destination_id = dest.id
ORDER BY origin_id
Check the demo here.

Related

How to set up crosstab queries to count days for negative stock counts?

Hello Stack overflow (and anyone googling similar questions in the future)!
I have a dataset that regularly reports which products are absent on a warehouse stockcheck, which I am trying to use to analyse when stock is or isn’t available. I’m essentially trying to identify “Has a part been reported as missing? -> If so, count the number of days it is missing until another part in the same category is reported as missing, but the original part was not reported as missing on that date (as we can assume it’s back in stock)”.
I’ve managed to make this work in excel, but my spreadsheet began to die from the calculation of 5 locations worth of categories and parts, let alone across the 600+ I’m working on! As a result, I’m trying to set up a similar function in Access to analyse which, and for how long, parts were out of stock.
My dataset looks something like:
Location number
Location
Category
Date reported
Part Number
Part Description
Order number
1
London
Car
03/06/2021
2021
Wheel A
1
2
London
Bus
03/06/2021
1491
Seat C
2
3
Manchester
Car
01/06/2021
2021
Wheel A
3
My assumptions are that:-
• My data is fed by individual workers who each cover a location, and check all stock for a random selection of categories each visit (with the idea that they cover all of their location’s categories within a certain number of visits) and record which parts are missing. There is no particular visit plan – it can be a random number of days between each visit. This data gets fed into a central table, which I have access to.
• As my workers may not check all categories in a location on each visit, I must assume that a previously reported missing part is OOS until they check products in the same category, but do not report that part again.
I made this work on excel by setting up another column that concatenated my location, part number, and date reported, and then set up three tables (all of which are essentially locations, categories, and parts down my X axis, and dates across the Y axis):-
• Table1, to look if my concatenated code was reported for each day (and if so, output 1 – essentially working in days) – essentially, was each part reported as missing for each category and location?
• Table2, to look if any parts were reported for each category, for each location – essentially, how many parts were reported for each category for each location, and a value greater than 0 means we can assume that that category at that location has been checked by my workers for that date.
• Table3, that for each location+category+day asked as a formula – IF(category was checked as per table2 = yes , pull the value of 1 for that part/location/category in table 1 , re-use yesterday’s value for this part/location/day in this table). For the 1st day in my date range, I used the values for table1 for that day as a “starting up” point.
When I look at table 3, I can visually the run of days products were out of stock, and can from there crunch numbers related to that, which is what I want!
My initial Access plan was to set up three crosstab queries, to mirror my three excel tables. I can make Table1 and Table2 very easily, but for the life of me can’t make table3 work (currently have a calculated expression that mirrors the formula I had in table 3, but something has gone amiss…).
I’m looking for a steer/advice on setting up the expression in my crosstab query, or other ideas/approaches I could use to calculate how long each part is missing for. Any help would be greatly appreciated, as I’ve lost my mind going in circles today!
Edit:-
Simplified dataset I'm working with:-
Location
Category
Date Reported
Part number
Part Description
Order number
Concatenate code
Concatenate Code 2
1
London
Car
03/06/2021
2021
Wheel
1
1443502021
1
London
Bus
03/06/2021
1491
Seat
2
1443501491
2
Manchester
Car
05/06/2021
2021
Wheel
3
2443522021
1
London
Car
05/06/2021
2021
Wheel
4
1443522021
1
London
Car
07/06/2021
2021
Wheel
5
1443542021
1
London
Bus
05/06/2021
1860
Seatbelt
6
1443521860
1
London
Bus
05/06/2021
1860
Seatbelt
7
1443521860
2
manchester
Bus
01/06/2021
1860
Seatbelt
8
2443481860
2
Manchester
Bus
06/06/2021
1860
Seatbelt
9
2443531860
2
manchester
Bus
04/06/2021
1491
Seat
10
2443511491
2
Manchester
Bus
06/06/2021
1491
Seat
11
2443531491
I'm trying to output something like (which I've made work in Excel):-
Location
Category
Part code
01/06/2021
02/06/2021
03/06/2021
04/06/2021
05/06/2021
06/06/2021
07/06/2021
1
London
Car
2021
1
1
1
1
1
London
Car
2626
1
London
Bus
1491
1
1
1
London
Bus
1860
1
1
2
Manchester
Car
2021
1
1
2
Manchester
Car
2626
2
Manchester
Bus
1491
1
1
1
2
Manchester
Bus
1860
1
1
1
1
3
Liverpool
Car
2021
3
Liverpool
Car
2626
3
Liverpool
Bus
1491
Or to return the value for how many concurrent days out of stock a part has been, like per day of this version:-
Location
Category
Part code
01/06/2021
02/06/2021
03/06/2021
04/06/2021
05/06/2021
06/06/2021
07/06/2021
1
London
Car
2021
1
2
3
4
1
London
Car
2626
1
London
Bus
1491
1
2
1
London
Bus
1860
1
2
2
Manchester
Car
2021
1
2
2
Manchester
Car
2626
2
Manchester
Bus
1491
1
2
3
2
Manchester
Bus
1860
1
2
3
1
3
Liverpool
Car
2021
3
Liverpool
Car
2626
3
Liverpool
Bus
1491
My Access sql (that I then turned into a crosstab) to identify ordered parts per day:
SELECT DISTINCT T_stores.[Store Nos], T_stores.[Store Name], t_Stands.Brand, t_Productlookup.TPND, t_Productlookup.TITLE, t_gapdata.Quantity, t_gapdata.[Requested Date]
FROM ((T_stores
INNER JOIN t_Stands ON T_stores.[Store Nos] = t_Stands.[Store Nos])
INNER JOIN t_gapdata ON (t_Stands.[Brand] = t_gapdata.[Brand]) AND (t_Stands.[Store Nos] = t_gapdata.[Store No]))
INNER JOIN t_Productlookup ON t_gapdata.[Part Number] = t_Productlookup.[EAN];
And likewise, to identfy is parts were ordered for a location's category:-
SELECT DISTINCT T_stores.[Store Nos], T_stores.[Store Name], t_Stands.Brand, t_Productlookup.TPND, t_Productlookup.TITLE, t_gapdata.Quantity, t_gapdata.[Requested Date]
FROM ((T_stores
INNER JOIN t_Stands ON T_stores.[Store Nos] = t_Stands.[Store Nos])
INNER JOIN t_gapdata ON (t_Stands.[Brand] = t_gapdata.[Brand]) AND (t_Stands.[Store Nos] = t_gapdata.[Store No]))
INNER JOIN t_Productlookup ON t_gapdata.[Part Number] = t_Productlookup.[EAN];
These first two work fine, but I'm struggling to put them together with some sort of Iif calculated field for a third query:-
SELECT First(q_gaps_per_product.[Store Nos]) AS [FirstOfStore Nos], First(q_gaps_per_product.[Store Name]) AS [FirstOfStore Name], First(q_gaps_per_product.Brand) AS FirstOfBrand, First(q_gaps_per_brand_store.[Order Id]) AS [FirstOfOrder Id], First(q_gaps_per_product.TPND) AS FirstOfTPND, First(q_gaps_per_product.TITLE) AS FirstOfTITLE, First(q_gaps_per_product.[Requested Date]) AS [FirstOfRequested Date], First(IIf([q_gaps_per_brand_store]![Requested Date]>=[q_gaps_per_product]![Requested Date],[Quantity],"PREVIOUS DAY")) AS Expr1, [q_gaps_per_product]![Store Nos] & [q_gaps_per_product]![Quantity] & [q_gaps_per_product]![TPND] AS Expr2
FROM q_gaps_per_product LEFT JOIN q_gaps_per_brand_store ON q_gaps_per_product.[Brand] = q_gaps_per_brand_store.[Brand]
GROUP BY [q_gaps_per_product]![Store Nos] & [q_gaps_per_product]![Quantity] & [q_gaps_per_product]![TPND];
Expr1 is supposed to be how many days a product is out of stock, with the idea that "PREVIOUS DAY" would return the same criteria for the previous day, to show either running gaps or that a product was in fact available as a 0, but I haven't got that far yet.
Expr2 is basically something I tried to make up to group the results by, as I had an insane number of results due to my janky table relationships.
I sort of think this query is DOA, and I need to go back to the drawing board to reproduce something like my Excel tables / how many days out of stock products have been concurrently out of stock before.
Sorry for the sheer storm of words!

MySQL table JOIN with LIKE without adding another ID column

I have two tables named "regions" and "city_list":
REGIONS TABLE:
r_id r_code r_name
1 REGION I Ilocos Region
2 REGION II Cagayan Valley
3 REGION III Central Luzon
4 REGION IV-A CALABARZON
5 REGION IV-B MIMAROPA
CITY_LIST TABLE:
city_id city_name city_region
32 Catbalogan REGION VIII (Eastern Visayas)
33 Cauayan REGION II (Cagayan Valley)
34 Cavite City REGION IV-A (CALABARZON)
35 Cebu City REGION VII (Central Visayas)
87 City of Naga REGION VII (Central Visayas)
I want to reference the regions table when a user selects a city name from the city_list table. For example:
User selects "Cauauyan" from a drop-down list, the server returns the region code which is the "r_code" column from the Regions table.
Can I use a JOIN statement with LIKE without adding a column for a region ID in the city_list table? Is it possible to get the value in city_region like "REGION II" without the "(Cagayan Valley)" and use that value to get r_id in the REGIONS table?
SELECT r.r_id
FROM REGIONS r
WHERE r.`r_code` IN(
SELECT LEFT(`CITY_LIST`.`city_region`,INSTR(`CITY_LIST`.`city_region`,"(")-1) AS Region_id FROM `CITY_LIST`);

Matching two columns based on the value of some column in a different table in MySQL

With a very limited knowledge of sql fighting to solve this query for last couple of hours:
Table: Airport
Code Country
---- -------
JFK USA
ARN Sweden
UMU Sweden
LAX USA
BER Germany
Table: Flight
Origin Destination
------ -----------
LAX JFK
ARN JFK
UMU ARN
JFK BER
The problem is to find the Airport which runs Domestic flight only, i.e, the destination airport is in the same country as the origin airport. The query is suppose to produce the following result:
DomesticAirport
---------------
LAX
UMU
A little help will be highly appriciated
This results in your desired output:
select f.origin
from flight f
join airport a1
on f.origin = a1.code
join airport a2
on f.destination = a2.code
where a1.country = a2.country
SQL Fiddle demo here: http://sqlfiddle.com/#!2/92363/5/0
Assuming by "run domestic flights" you mean that flights originating at the airport are all domestic, then you can do this by finding the countries for the origin and destination using two joins. Then aggregate the result by the original airport and use a having clause to filter the airports you want.
select f.origin
from flights f join
airport ao
on f.origin = ao.origin join
airport ad
on f.destination = ad.destination
group by f.origin, ao.country
having min(ad.country) = ao.country and max(ad.country) = ao.country

Search multiple tables in mysql

I have a table structured like this (not the actual data or fields, but the same structure applies):
ID | City Field2 Field 3
-------------------------------
1 New York Ohio data
2 Cincinnati data data
3 Los Angeles data Ohio
4 Cleveland data data
Then there's a second table something like this (again, not the actual data)
City State
-------------------------------
Los Angeles California
New York New York
Cincinnati Ohio
Cleveland Ohio
Houston Texas
etc.
I have a php web page that allows users to search the database; when they do, it will automatically print (in my example) the corresponding state from the second table after the city.
However, if the user searches for "Ohio", it should return all four records, even though "Ohio" doesn't exist in the first table. It looks like I'd have to run multiple queries - find the search term in the first table, find it again in the second table, and then search for column 1 of the second table in the first table (and then join the results). Is there an easier way to do that? (I'm fairly new to MySQL.)
Have you tried using a UNION?
SELECT City FROM table1 WHERE Field2 = 'Ohio' OR Field3 = 'Ohio'
UNION ALL
SELECT City FROM table2 WHERE State = 'Ohio'
It would be helpful to see what your query looks like.

MySQL: Selecting One Record When Others Have Same Data

I have a table of cities that all share the same area code:
367 01451 Harvard Worcester Massachusetts MA 978 Eastern
368 01452 Hubbardston Worcester Massachusetts MA 978 Eastern
369 01453 Leominster Worcester Massachusetts MA 978 Eastern
The table has multiple area codes, all with multiple cities.
What I'd like to do is only select one city from each area code and delete any extra cities from duplicate area codes. What would be the best query to accomplish this?
I believe:
Mysql4: SQL for selecting one or zero record
Is coming close to what I need but didn't quite get what/how those answers were working.
Note The "978" row is the "area_code" row, table name is "zip_code".
DELETE c.*
FROM zip_code c
JOIN (
SELECT area_code, MIN(id) AS mid
FROM zip_code
GROUP BY
area_code
) co
ON c.area_code = co.area_code
AND c.id <> co.mid