visitor (0 QPoints)
  • FR
  • EN
  • NL
  • DE
  • ES
315 experts, 1193 registered users, 1659 questions already answered
European Experts Exchange, the very best site for high-quality IT solutions

New Improved Search!

 


05/10/2011 1h30 : Steve Jobs is dead, the father of Apple ][ is gone, we are all orphaned.

Databases :: MySql :: Nested SELECT


By: Squibi U.S.A.  Date: 09/01/2003 00:00:00  English  Points: 500 Status: Answered
Quality : Excellent
Hi,

I have a MySQL database with the following tables:

Users
Domains
Databases
Links

Basically, the relationships are as follows:

Users 1-* Domains 1-* Databases 1-* Links

Where 1-* signifies a 1 to many relationship.

Ok, I'm trying to write a nested SELECT statement which retrieves the Links for all Databases for all Domains for a specific user.

I figure the following should work, but it doesn't:

SELECT * FROM links WHERE 'database_id' = (SELECT id FROM 'databases' WHERE domain_name = (SELECT name FROM domains WHERE user_id = 'test_id'))

I found through trial and error, that I would have to put '' marks around 'databases', otherwise that throws an error. Any ideas why that is? Is databases a reserved word?

Anything obvious I'm doing wrong there?!

Thanks in advance,


By: VGR Date: 09/01/2003 19:14:00 English  Type : Answer
of course 'databases' is a reserved keyword. It's used for example like this : "show databases;"

then, nested selects are unavailable in mySql. They are usually unnecessary, though.

proceed with a create temporary table XXX select ... and then use left JOINs or other records' crossing between your tables.


this table will be dropped when the script finishes.

I ***guess*** that you CAN NOT do this in a single SQL phrase. You will end with a script. This given, why not use a simple PHP page to process your data ?

create temporary table names select name FROM domains WHERE user_id = 'test_id';
// here access each row in a loop on $curid
create temporary table mydb select id FROM 'databases' WHERE domain_name = $curid;
// sub-loop on $curdbid
SELECT * FROM links WHERE 'database_id' = $curdbid;


HTH
By: Mark_IV Date: 09/01/2003 19:15:00 English  Type : Comment
MySQL, up until 4.0 only supported nested queries in the form INSERT ... SELECT ... and REPLACE ... SELECT ....

I am pretty sure that subselects are being implemented in the 4.1

Make sure you have the latest version of MySQL.

Hope this helps!
By: VGR Date: 09/01/2003 19:21:00 English  Type : Comment
you copied the doc' ;-)

I would not name "insert into... select from..." a nested select either ;-)

extract from the doc' :
1.7.4.1 SubSELECTs

MySQL Server until version 4.0 only supports nested queries of the form INSERT ... SELECT ... and REPLACE ... SELECT .... You can, however, use the function IN() in other contexts. Subselects are being implemented in the 4.1 development tree.

Meanwhile, you can often rewrite the query without a subselect:

SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);

This can be rewritten as:

SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;

The queries:

SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);
SELECT * FROM table1 WHERE NOT EXISTS (SELECT id FROM table2
WHERE table1.id=table2.id);

Can be rewritten as:

SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id
WHERE table2.id IS NULL;

For more complicated subqueries you can often create temporary tables to hold the subquery. In some cases, however, this option will not work. The most frequently encountered of these cases arises with DELETE statements, for which standard SQL does not support joins (except in subselects). For this situation there are two options available until subqueries are supported by MySQL Server.

The first option is to use a procedural programming language (such as Perl or PHP) to submit a SELECT query to obtain the primary keys for the records to be deleted, and then use these values to construct the DELETE statement (DELETE FROM ... WHERE ... IN (key1, key2, ...)).


By: Mark_IV Date: 09/01/2003 19:41:00 English  Type : Comment
Yup! :)


By: VGR Date: 09/01/2003 19:52:00 English  Type : Comment
FYI, I'm using 4.2.3 but still refuses to use sub-selects ; they are less clean, more difficult to maintain, and take a loooooong time to write correctly (and use and abuse of aliases). I prefer code that is quickly written, is efficient "as per se", and works from the start ;-)

As for the predictable next future of MySql, I'm not interested in stored procedures either, and no more by the triggers ;-)

Only transactions (commit/rollback) may interest me if ***ever*** a customer needs them ;-)
By: Squibi Date: 09/01/2003 20:01:00 English  Type : Comment
Ok, yeah, I originally started doing it in PHP code, using loops and arrays, but I figured it'd be more efficient to do it in one line of SQL, no?
By: VGR Date: 09/01/2003 20:39:00 English  Type : Comment
not sure

IMHO, the lesser the DB does "dirty tricks" behind the scene (optimizer, queries with sub-queries with sub-queries, unnumbereable aliases, LISP-style parentheses, 10 miles long SQL phrases, implicit indexes, and such), the better I feel.

Given that :
-nor mySql nor PHP do compile the SQL processing for later faster execution,
-the SQL interpreter HAS TO do THE SAME BASIS as my PHP "program" (at a MINIMUM), ie looping somehow, fetching, etc

I conclude that I prefer doing it in PHP.

CQFD
By: VGR Date: 09/01/2003 20:40:00 English  Type : Comment
and obviously, it's less questionable than SQL sub-sub-sub-sub-queries LEFT joindes NOT NULL on alias USING INDEX () ... ;-))
By: Squibi Date: 10/01/2003 07:31:00 English  Type : Comment
Hehe, yeah... Well, I've done it in PHP now and it works a treat! Thanks...
By: VGR Date: 10/01/2003 07:38:00 English  Type : Comment
you are welcome, I like to help : I'm lurking around here exactly for that 8-)

Do register to be able to answer

EContact
browser fav
page generated in 320.607900 milliseconds

Why Google AdSense ads ?

compteur
 Ranking-Hits PageRank for this page