MySQL table JOIN with LIKE without adding another ID column - mysql

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`);

Related

SQL: how to select where one column does not match another column for ALL records within a given group

I have a table named sales in a MySQL database that looks like this:
company manufactured shipped
Mercedes Germany United States
Mercedes Germany Germany
Mercedes Germany United States
Toyota Japan Canada
Toyota Japan England
Audi Germany United States
Audi Germany France
Audi Germany Canada
Tesla United States Mexico
Tesla United States Canada
Tesla United States United States
Here is a Fiddle: http://www.sqlfiddle.com/#!17/145ff/3
I would like to return the list of companies that ship ALL of their products internationally (that is, where the value in the manufactured column differs from the value in the shipped column for ALL records of a particular company).
Using the example above, the desired result set would be:
company
Toyota
Audi
Here is my (hackish) attempt:
WITH temp_table AS (
SELECT
s.company AS company
, SUM(CASE
WHEN s.manufactured != s.shipped THEN 1
ELSE 0
END
) AS count_international
, COUNT(s.company) AS total_within_company
FROM
sales s
GROUP BY
s.company
)
SELECT
company
FROM
temp_table
WHERE count_international = total_within_company
Essentially, I count the instances where the columns do not match. Then I check whether the sum of those mismatched instances matches the number of records within a given group.
This approach works, but it's far from an elegant solution!
Can anyone offer advice as to a more idiomatic way to implement this query?
Thanks!
We can GROUP BY company and use a HAVING clause to say all countries in shipped must differ to the country in manufactured:
SELECT company
FROM sales
GROUP BY company
HAVING COUNT(CASE WHEN manufactured = shipped THEN 1 END) = 0;
Try out here: db<>fiddle
The fiddle linked in the question is a Postgres DB, but MySQL is taged as DBMS.
In a MySQL DB, the above query can be simplified to:
SELECT company
FROM sales
GROUP BY company
HAVING SUM(manufactured = shipped) = 0;
In a Postgres DB, this is not possible.
You have to think in sets... you want to display all without a match -- find the matches display the rest
SELECT DISTINCT company
FROM sales
WHERE company NOT IN (
SELECT company
FROM sales
WHERE manufactured = shipped
)

Inner join with multiple conditions on one column

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.

Fetch fixed set of duplicate records from table

I want to fetch records from a table that contains duplicate records. I want the output to be like only two duplicate records from each set of duplicate records in overall record output set.
example-
Name
Country
John
India
Mark
India
Chris
Russia
Feggy
England
Rain
Russia
Monesy
Russia
Bhumi
India
Peter
England
Bruice
England
Radhe
India
Output should have only two duplicate set of records from all duplicate of similar type as we can see in output below the country is repeating only two times and it took only first two counters of duplicate records in final record set -
Name
Country
John
India
Mark
India
Chris
Russia
Feggy
England
Rain
Russia
Peter
England
You can number the lines by the window and select only the first N.
Sorting should be chosen according to the business logic of the query.
For example:
;WITH numbered_name AS
(
SELECT *
, ROW_NUMBER() OVER (PARTITION BY t.Country ORDER BY t.Name) rn
FROM table t
)
SELECT Name
, Country
FROM numbered_name
WHERE rn <= 2

Search for field contents contained in other records

I have a list table having over 200,000 rows with city column. Assume that it contains following data:
rowid city
1 Toronto
2 Milton
3 Hamilton
4 Delhi
5 New Delhi
6 Markham
I want to find all records where the city is contained in another row, e.g. Milton (row 2) is contained in Hamilton (row 3) and Delhi (row 4) is contained in New Delhi (row 5). I expect the following output:
rowid city rowid2 city2
2 Milton 3 Hamilton
4 Delhi 5 New Delhi
Can a single query get the output I am looking for?
Thanks.
Assume table name is 'cities'. Following SQL query should work:
select
c2.rowid, c2.city, c1.rowid, c1.city
from
cities c1
inner join
cities c2
on instr(c1.city,c2.city)
and c1.rowid != c2.rowid

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