MySQL query question - mysql

I have a database containing the route data for airlines.
Some of the attributes are sources_airport_ID, destination_airport_ID, and airline(which supports the route from source to destination).
I'm trying to self join the table to look up airlines that have the same route (in other words, same sources_airport_ID and destination_airport_ID).
I was using the query as follows:
(table name = routes)
SELECT t1.*, t2.*
FROM routes AS t1, routes AS t2
WHERE t1.sources_airport_ID = t2.sources_airport_ID
AND t1.destination_airport_ID = t2.destination_airport_ID
AND t1.airline != t2.airline
When I execute this query, I get an error saying that the maximum execution time exceeded 300 seconds. I'm not sure if I'm using the correct query for this purpose.
Can anyone help me with the query? I'm using xampp as my database.
Thanks in advance!
EDIT:
My primary key is ID, which is just an auto-increment value.
There are 64,114 records in routes table.

Try using JOIN syntax:
SELECT t1.*, t2.*
FROM routes AS t1
JOIN routes AS t2
ON t1.sources_airport_ID = t2.sources_airport_ID
AND t1.destination_airport_ID = t2.destination_airport_ID
AND t1.airline != t2.airline
But as suggested do make sure that the fields sources_airport_ID, destination_airport_ID and airline are indexed in the routes table.

Try something like this:
SELECT r.*, count(r.sources_airport_ID) as occ
FROM routes r
GROUP BY sources_airport_ID, destination_airport_ID, airline
HAVING occ > 1;

Related

How to select from multiple tables with join

I am trying to select all data from databases Startuptier1 and connections where the company id = $select. Both databases have the column 'companyid' with the corresponding row.
None of the information regarding joins that I have found so far online is working. I have also tried unions. I assume I am missing something very obvious?
$sql = "SELECT * FROM startuptier1
JOIN connections ON startuptier1.companyid = connections.companyid
WHERE companyid= '$select';";
I expect to get the data from both databases from what I've read so far but all I'm getting is an SQL Error.
You are getting an error probably because, companyid is present in both tables and mysql cannot decide on which column to fire where condition:
Try the modified query:
$sql = "SELECT * FROM startuptier1
JOIN connections ON
startuptier1.companyid = connections.companyid
WHERE startuptier1.companyid in (".$select.")";
Note: Your database account should have appropriate permission. You should be able to perform operations on every database that you are accessing via joins
EXAMPLE 1:
SELECT * FROM DB1.table1 t1 JOIN DB2.table2 t2 ON t2.column2 = t1.column1;
EXAMPLE 2:
SELECT db1.artist.name, db2.painting.title
FROM db1.artist INNER JOIN db2.painting
ON db1.artist.a_id = db2.painting.a_id;

JOIN on keys that don't have the same value

I am trying to do an INNER JOIN on two tables that have similar values, but not quite the same. One table has a fully qualified host name for its primary key, and the other the hosts short name, as well as the subdomain. It it safe to assume that the short name and the subdomain together are unique.
So I've tried:
SELECT table1.nisinfo.* FROM table1.nisinfo INNER JOIN table2.hosts ON (table1.nisinfo.shortname + '.' + table1.nisinfo.subdomainname + '.domain.com') = table2.hosts.fqhn WHERE table2.hosts.package = 'somepkg';
This doesn't return the results I expect, it returns the first result hundreds of times. I'd like to return distinct rows. It takes a long time to run as well.
What am I doing wrong? I was thinking of running a subquery to get the hostnames, but I don't know what the right path from here is.
Thank you!
You can use group by in your query so you can achieve the desired results you want
please see this two links
Group by with 2 distinct columns in SQL Server
http://www.sqlteam.com/article/how-to-use-group-by-with-distinct-aggregates-and-derived-tables
Try putting your results into a temp table and then view the table to make sure that the columns are as expected.
SELECT table1.nisinfo.*, table1.nisinfo.shortname + '.' + table1.nisinfo.subdomainname + '.domain.com' AS ColID
INTO #temp
FROM table1.nisinfo;
Select *
from #temp INNER JOIN table2.hosts ON ##temp.ColID = table2.hosts.fqhn
WHERE table2.hosts.package = 'somepkg'
;
Put a Group By clause at the end of the second statement
So in this case, I used a subquery to get the initial results, and then used a join.
SELECT table1.nisinfo.* FROM table1.nisinfo JOIN (SELECT distinct(fqhn) FROM table2.hosts WHERE package = 'bash') AS FQ ON ((SUBSTRING_INDEX(FQ.fqhn, '.', 1)) = table1.nisinfo.shortname);

Finding duplicates, which shares a common property

I’m trying to select duplicated nodes on a Drupal site, basically i need to select nodes that share a common ‘tnid' (translation node id), and also share the same ‘language’.
But i can’t figure out how to write the query, i think i did the first part, finding nodes with common tnid, like so
SELECT origin.nid, origin.tnid, origin.title, origin.language
FROM node AS origin
JOIN (select nid, tnid from node
group by tnid having count(tnid) > 1) common_tnid ON common_tnid.tnid = origin.tnid
#JOIN node common_lang ON common_lang.language = origin.language
AND common_lang.tnid = origin.tnid
WHERE origin.tnid != 0
Considering the language part is my big hurdle, how would i add that to the query? I tried a bunch of stuff, thus. the comment.
Try this:
SELECT
table1.nid nid,
table1.tnid tnid,
table1.language language,
table1.title title
FROM
(
SELECT *
FROM
table1
GROUP BY
tnid, language
HAVING
COUNT(*) > 1
) dupe
LEFT JOIN
table1
ON dupe.tnid = table1.tnid
AND dupe.language = table1.language
SQL Fiddle: http://sqlfiddle.com/#!9/294cc/1/0
You can try something like this
SELECT origin.id AS origin_id, common.id AS common_id
FROM node AS origin
INNER JOIN node AS common ON common.language = origin.language AND common.tnid = origin.tnid AND origin.id != common.id
I dont know if your table has id field but you can change to some field that is different in both rows

MySQL trim(concat ...)

What is wrong with this query?
SELECT DISTINCT source,
source_description,
url
FROM staging_census
WHERE Trim(Concat(source, source_description, url)) NOT IN (SELECT
Trim(Concat(source,
source_description, url))
FROM dim_source);
The objective is to pull only the records where a combination of Source, Source_Description and URL that does not exist (which is true in my case). However, if it sees a match in only one column it ignores it.
MySQL Newbie... if there is a better way for this query I would appreciate it.
Try this:
SELECT DISTINCT Source, Source_Description, URL
FROM Staging_Census
WHERE CONCAT(TRIM(Source), TRIM(Source_Description0, TRIM(URL))) NOT IN (SELECT CONCAT(TRIM(Source), TRIM(Source_Description0, TRIM(URL))) FROM DIM_Source);
OR
SELECT DISTINCT SC.Source, SC.Source_Description, SC.URL
FROM Staging_Censusc SC
LEFT JOIN DIM_Source DS ON (TRIM(SC.Source), TRIM(AC.Source_Description0, TRIM(SC.URL)) = (TRIM(DS.Source), TRIM(DS.Source_Description0, TRIM(DS.URL))
WHERE DS.DimsourceId IS NULL

Best way to reference an outer query / subquery?

I'm trying to reference a field from the 1st select table in the 3rd select(subquery) table.
However, that field isn't recognized when it goes to that sub-level of a query.
The php code I'm working on uses sql to return part of the sql command (string) that will be used in other places.
I've came up with this example that shows up the kind of nested querys that I want to solve.
In here I'm trying to get the name and emails of users that are working at night and have a matching job rank for an available job:
tables -----------> fields
table_users -> [user_id, name, email, rank, ...]
table_users_jobs -> [user_id, job_id, period, ....]
table_jobs -> [job_id, status, rank, ...]
-- sql calling code -> $rank = "t1.rank"; get_users_info_by_rank($rank);
-- maybe using: SET #rank = NULL; SELECT #rank := $rank, t1.name, ...
SELECT t1.name, t1.email
FROM table_users as t1
WHERE t1.user_id IN (
SELECT t2.user_id
FROM table_users_jobs as t2
WHERE t2.period = 'night' AND
t2.job_id IN (
-- avaiable jobs to that rank -> get_job_ranks_sql($rank);
SELECT t3.job_id
FROM table_jobs as t3
-- maybe using: t3.rank = #rank
WHERE t3.rank = t1.rank AND
t3.status = 'avaiable_position')
)
Working a little I guess I could avoid the 3rd level select problem. Nevertheless the point is that I'm trying to reuse sql code like the function that gives me the job_id of the rank that I chose:
function get_job_ranks_sql($rank){
//probably 't3' will be renamed for something more unique
return 'SELECT t3.job_id
FROM table_jobs as t3
WHERE t3.rank = '.$rank.' AND
t3.status = "available_position")';
}
Even using php I'm trying to make it generic to maybe use with another language if possible.
The sql version using is MySQL 5.1.41
Actually I think it's possible the way I want, by using sql variables like #rank, but I'm not sure if it's slower and if there are other better ways to do it.
Thanks in advance for any help :)
So, as one commenter pointed out, I think you would do much better off using JOINS, than sub-selects. For example, if I am reading your query/problem correctly, you could do a join query like this:
SELECT t1.name, t1.email, t3.job_id
FROM table_users t1
LEFT JOIN table_users_job t2
ON t1.user_id = t2.user_id
LEFT JOIN table_jobs t3
ON t3.job_id = t2.job_id
WHERE t2.period = 'night
AND t3.status = 'available_position'
Which is a lot more concise, easier to read, and is easier on your database. But doing this would prevent you from modularizing your SQL. If that is really important, you might consider storing such queries in Stored Procedure. This way, you can actually get a SP to return a list of results. Take a look at this tutorial:
http://www.wellho.net/resources/ex.php4?item=s163/stp4
Of course, that doesn't really solve your problem of being able to access variables at the lower levels of a sub select, but it would make your SQL easier to manage, and make it available to other language implementations, as you mentioned might be a need for you.
Something else to consider, in the bigger picture, would be migrating to a PHP framework that provides an ORM layer, where you could make those tables into objects, and then be able to access your data with much greater ease and flexibility (usually). But that is very 'big picture' and might not be suitable for your project requirements. One such framework that I could recommend, however, is CakePHP.