Re: [PHP] formulate nested select

2009-04-02 Thread Ian
On 31 Mar 2009 at 18:15, PJ wrote:

snip

  But I see that I may be trying to do too much - I thought of showing how
  many books were listed under each letter of the alphabet but I don't see
  how it can be done in any simiple way as it would mean that I would have
  to do the select once with the ORDER BY and a second time without it
  just to get the number of listing. If there are a lot of books, like
  thousands, it might slow down things.
  I suppose I could live with ORDER BY title as that does not require
  another effort.
  Any thoughts or suggestions?

Hi,

Sounds like you need to use the GROUP BY functions of MySQL

This SQL is probably wrong because I don't remember seeing your schema (and am 
too 
busy here to go looking!)

SELECT 
LEFT(last_name, 1 ) as Letter, Count(bookID) as NumberOfBooks
FROM 
books INNER JOIN tables that join them...
GROUP BY Letter
ORDER BY Letter ASC


You will have to play around with that to get the right results.  But it should 
give you 
something like:

Letter,NumberOfBooks
A,47
B,21
C,8
...

The MySQL manual has more info:
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions-and-modifiers.html

Regards

Ian
-- 


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-31 Thread PJ
Jim Lucas wrote:
 Chris wrote:
 PJ wrote:
 I cannot find anything on google or the manuals/tutorials that gives
 some kin of clear explanation of how to so nested selects with where or
 whatever.
 I have three tables: books, authors and book-authors.
 I need to retrieve only those books whose author's names begin with A.
 I have tried several maniipulations of where and select with select
 subqueries and I cannot get results from the queries.
 For example
 SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
 LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id =
 c.bookID snip

 Not really a php question :P

 You don't need a subquery for this. You can join all of the tables
 together and just use the where clause to cut down your results, but
 I'll give an example of both.

 select *
 from
   books b inner join book_authors c on (b.id=c.bookId)
   inner join authors a on (a.id=c.authorId)
 where
   left(a.last_name = 'A');

 correct me if I'm wrong, but did you use the left() function
 in-correctly?

 The documentation shows a different way to use it then you describe.

 Something more like the following:

 WHERE
LEFT(a.last_name, 1) = 'A';

 But that would be case-sensitive...

 So, something like this would work better IMHO

 WHERE
UPPER(LEFT(a.last_name, 1)) = 'A';

 or

 WHERE
a.last_name ILIKE 'A%';

 would do the trick

 or

 select *
 from
   books b inner join book_authors c on (b.id=c.bookId)
 where
   c.authorId in (
 select id from authors where left(last_name='A')

 Again...

 SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')

 but yet again, case-sensitive...

 SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A')
 or
 SELECT id FROM authors WHERE last_name ILIKE 'A%'

 would do the trick

   );




Thank you for the suggestions, gentlemen.
As to the case sensitivity, since the authors' names must be written
with the first letter in uppercase, even Anonymous or Unknown I
assume I don't need to specify uppercase. Or does it really make a
difference? Glad to learn of the option, though.

I'm just starting on the listing of the books by author and just
realized that the sorting should be by author (last name). Can I foresee
a problem in that since the last_name is in associative tables and not
in the book table? Or does the JOIN incorporate the last_name in the
results?

-- 
unheralded genius: A clean desk is the sign of a dull mind. 
-
Phil Jourdan --- p...@ptahhotep.com
   http://www.ptahhotep.com
   http://www.chiccantine.com/andypantry.php


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-31 Thread PJ
I must be doing something wrong. Can't figure it out even though I've
been searching the manuals  tutorials, it still does not work. Here is
the exact code that I have tried; the first version is commented out and
obviously does not work either (the spelling, the table names and column
names are correct):

$books = array();
/*$SQL = SELECT * FROM book b
JOIN book_author c
ON b.id = c.bookID
JOIN author a ON a.id = c.authID
WHERE LEFT(a.last_name,1) = $Auth
ORDER BY $sort $dir
LIMIT $offset, $records_per_page; */

$SQL = SELECT * FROM book b
INNER JOIN book_author c
ON b.id = c.bookID
WHERE c.authID = (SELECT id FROM author a WHERE LEFT(a.last_name, 1
) = $Auth )
ORDER BY $sort $dir
LIMIT $offset, $records_per_page;
if ( ( $results = mysql_query($SQL, $db) ) !== false ) {
while ( $row = mysql_fetch_assoc($results) ) {
$books[$row['id']] = $row;
}
}
echo auth = :, $Auth ; --- returns auth = :A (my quotes)
var_dump($results);  --- returns boolean false (my quotes)

Now, this:
$SQL = select *
from book b
inner join book_author c
on (b.id = c.bookID)
inner join author a on (a.id = c.authID)
where left(a.last_name, 1 ) = $Auth;
if ( ( $results = mysql_query($SQL, $db) ) !== false ) {
while ( $row = mysql_fetch_assoc($results) ) {
$books[$row['id']] = $row;  --- returns Parse error:
syntax error, unexpected '[', expecting ']' in this line
There seems to be something odd in the query... and yet, it all three
look right to me... could there be some inconsistency in the tables,
like skipped records or a record in a column that is non-existent in a
corresponding column?


Jim Lucas wrote:
 Chris wrote:
 PJ wrote:
 I cannot find anything on google or the manuals/tutorials that gives
 some kin of clear explanation of how to so nested selects with where or
 whatever.
 I have three tables: books, authors and book-authors.
 I need to retrieve only those books whose author's names begin with A.
 I have tried several maniipulations of where and select with select
 subqueries and I cannot get results from the queries.
 For example
 SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
 LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id =
 c.bookID snip

 Not really a php question :P

 You don't need a subquery for this. You can join all of the tables
 together and just use the where clause to cut down your results, but
 I'll give an example of both.

 select *
 from
   books b inner join book_authors c on (b.id=c.bookId)
   inner join authors a on (a.id=c.authorId)
 where
   left(a.last_name = 'A');

 correct me if I'm wrong, but did you use the left() function
 in-correctly?

 The documentation shows a different way to use it then you describe.

 Something more like the following:

 WHERE
LEFT(a.last_name, 1) = 'A';

 But that would be case-sensitive...

 So, something like this would work better IMHO

 WHERE
UPPER(LEFT(a.last_name, 1)) = 'A';

 or

 WHERE
a.last_name ILIKE 'A%';

 would do the trick

 or

 select *
 from
   books b inner join book_authors c on (b.id=c.bookId)
 where
   c.authorId in (
 select id from authors where left(last_name='A')

 Again...

 SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')

 but yet again, case-sensitive...

 SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A')
 or
 SELECT id FROM authors WHERE last_name ILIKE 'A%'

 would do the trick

   );






-- 
unheralded genius: A clean desk is the sign of a dull mind. 
-
Phil Jourdan --- p...@ptahhotep.com
http://www.ptahhotep.com
http://www.chiccantine.com/andypantry.php

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-31 Thread Ian
On 31 Mar 2009 at 9:08, PJ wrote:

 I must be doing something wrong. Can't figure it out even though I've
 been searching the manuals  tutorials, it still does not work. Here is
 the exact code that I have tried; the first version is commented out and
 obviously does not work either (the spelling, the table names and column
 names are correct):
 
 $books = array();
 /*$SQL = SELECT * FROM book b
 JOIN book_author c
 ON b.id = c.bookID
 JOIN author a ON a.id = c.authID
 WHERE LEFT(a.last_name,1) = $Auth
 ORDER BY $sort $dir
 LIMIT $offset, $records_per_page; */
 
 $SQL = SELECT * FROM book b
 INNER JOIN book_author c
 ON b.id = c.bookID
 WHERE c.authID = (SELECT id FROM author a WHERE LEFT(a.last_name, 1
 ) = $Auth )

Hi,

I think this should be '$Auth' as MySQL will be expecting a string.


 ORDER BY $sort $dir
 LIMIT $offset, $records_per_page;
 if ( ( $results = mysql_query($SQL, $db) ) !== false ) {
 while ( $row = mysql_fetch_assoc($results) ) {
 $books[$row['id']] = $row;
 }
 }
 echo auth = :, $Auth ; --- returns auth = :A (my quotes)
 var_dump($results);  --- returns boolean false (my quotes)
 
 Now, this:
 $SQL = select *
 from book b
 inner join book_author c
 on (b.id = c.bookID)
 inner join author a on (a.id = c.authID)
 where left(a.last_name, 1 ) = $Auth;
 if ( ( $results = mysql_query($SQL, $db) ) !== false ) {
 while ( $row = mysql_fetch_assoc($results) ) {
 $books[$row['id']] = $row;  --- returns Parse error:
 syntax error, unexpected '[', expecting ']' in this line
 There seems to be something odd in the query... and yet, it all three
 look right to me... could there be some inconsistency in the tables,
 like skipped records or a record in a column that is non-existent in a
 corresponding column?

Looks like there is a double quote (  ) missing from the end of the $SQL 
variable.

When building complex SQL queries for use in PHP I usually test them in the 
mysql 
command line client or a gui such as HeidiSQL first to make sure I am getting 
the 
expected results.  

Also you could try printing the SQL statement to the web page to make sure it 
looks as 
expected.

You can try checking for a MySQL error within PHP by using these functions:

mysql_errno()
mysql_error()

Regards

Ian
-- 



 
 
 Jim Lucas wrote:
  Chris wrote:
  PJ wrote:
  I cannot find anything on google or the manuals/tutorials that gives
  some kin of clear explanation of how to so nested selects with where or
  whatever.
  I have three tables: books, authors and book-authors.
  I need to retrieve only those books whose author's names begin with A.
  I have tried several maniipulations of where and select with select
  subqueries and I cannot get results from the queries.
  For example
  SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
  LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id =
  c.bookID snip
 
  Not really a php question :P
 
  You don't need a subquery for this. You can join all of the tables
  together and just use the where clause to cut down your results, but
  I'll give an example of both.
 
  select *
  from
books b inner join book_authors c on (b.id=c.bookId)
inner join authors a on (a.id=c.authorId)
  where
left(a.last_name = 'A');
 
  correct me if I'm wrong, but did you use the left() function
  in-correctly?
 
  The documentation shows a different way to use it then you describe.
 
  Something more like the following:
 
  WHERE
 LEFT(a.last_name, 1) = 'A';
 
  But that would be case-sensitive...
 
  So, something like this would work better IMHO
 
  WHERE
 UPPER(LEFT(a.last_name, 1)) = 'A';
 
  or
 
  WHERE
 a.last_name ILIKE 'A%';
 
  would do the trick
 
  or
 
  select *
  from
books b inner join book_authors c on (b.id=c.bookId)
  where
c.authorId in (
  select id from authors where left(last_name='A')
 
  Again...
 
  SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')
 
  but yet again, case-sensitive...
 
  SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A')
  or
  SELECT id FROM authors WHERE last_name ILIKE 'A%'
 
  would do the trick
 
);
 
 
 
 
 
 
 -- 
 unheralded genius: A clean desk is the sign of a dull mind. 
 -
 Phil Jourdan --- p...@ptahhotep.com
 http://www.ptahhotep.com
 http://www.chiccantine.com/andypantry.php
 
 -- 
 PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php



-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-31 Thread PJ
Ian wrote:
 On 31 Mar 2009 at 9:08, PJ wrote:

   
 I must be doing something wrong. Can't figure it out even though I've
 been searching the manuals  tutorials, it still does not work. Here is
 the exact code that I have tried; the first version is commented out and
 obviously does not work either (the spelling, the table names and column
 names are correct):

 $books = array();
 /*$SQL = SELECT * FROM book b
 JOIN book_author c
 ON b.id = c.bookID
 JOIN author a ON a.id = c.authID
 WHERE LEFT(a.last_name,1) = $Auth
 ORDER BY $sort $dir
 LIMIT $offset, $records_per_page; */

 $SQL = SELECT * FROM book b
 INNER JOIN book_author c
 ON b.id = c.bookID
 WHERE c.authID = (SELECT id FROM author a WHERE LEFT(a.last_name, 1
 ) = $Auth )
 

 Hi,

 I think this should be '$Auth' as MySQL will be expecting a string.
   
Hmmm That was it.  I'm not clear on this... what was MySQL getting?
if not a string...
sorry for my ignorance...

   
 ORDER BY $sort $dir
 LIMIT $offset, $records_per_page;
 if ( ( $results = mysql_query($SQL, $db) ) !== false ) {
 while ( $row = mysql_fetch_assoc($results) ) {
 $books[$row['id']] = $row;
 }
 }
 echo auth = :, $Auth ; --- returns auth = :A (my quotes)
 var_dump($results);  --- returns boolean false (my quotes)
 
 Now, this:
 $SQL = select *
 from book b
 inner join book_author c
 on (b.id = c.bookID)
 inner join author a on (a.id = c.authID)
 where left(a.last_name, 1 ) = $Auth;
 if ( ( $results = mysql_query($SQL, $db) ) !== false ) {
 while ( $row = mysql_fetch_assoc($results) ) {
 $books[$row['id']] = $row;  --- returns Parse error:
 syntax error, unexpected '[', expecting ']' in this line
 There seems to be something odd in the query... and yet, it all three
 look right to me... could there be some inconsistency in the tables,
 like skipped records or a record in a column that is non-existent in a
 corresponding column?
 

 Looks like there is a double quote (  ) missing from the end of the $SQL 
 variable.

 When building complex SQL queries for use in PHP I usually test them in the 
 mysql 
 command line client or a gui such as HeidiSQL first to make sure I am getting 
 the 
 expected results.  

 Also you could try printing the SQL statement to the web page to make sure it 
 looks as 
 expected.

 You can try checking for a MySQL error within PHP by using these functions:

 mysql_errno()
 mysql_error()

 Regards

 Ian
   


-- 
unheralded genius: A clean desk is the sign of a dull mind. 
-
Phil Jourdan --- p...@ptahhotep.com
   http://www.ptahhotep.com
   http://www.chiccantine.com/andypantry.php


-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-31 Thread PJ
Gentlemen  all others,
The problem was partly fixed with ' ' around $Auth... but...
somehow, I see that the results do not work with the rest of the script.
The results give a an array within an array - so this mucks up all the
rest which is set up to deal with only the book table. The count() is
off as it shows the results_per_page setting and the pagination is off -
it shows 10 books but only displays 5 entries (from 5 arrays which, I
suppose is the reason for the coun() showing 10. The first page shows 5,
but the second indicates 7 books but displays only 6...
Now, I suppose that there are 2 ways to fix things:
1. Redo the rest of the script (a royal pain, I suspect)
or
2. SELECT only the books that are attributed to the targeted authors -
which is what I wanted to do in the first place. Something like:

$SQL = SELECT * FROM book b
WHERE b.id = (SELECT book_author.bookID WHERE book_author.authID
= (SELECT author.id WHERE LEFT(author.last_name, 1 ) = '$Auth');

I want to avoid joins as that seems to screw up the rest of the code
which is in an include page that needs to be repeated as long as there
are letters in the alphabet.
I'll try to figure something out, but as somebody not too optimistic
once said: it sure don't look too good (American, I believe...) :-)
 Jim Lucas wrote:
 Chris wrote:
 PJ wrote:
 I cannot find anything on google or the manuals/tutorials that gives
 some kin of clear explanation of how to so nested selects with where or
 whatever.
 I have three tables: books, authors and book-authors.
 I need to retrieve only those books whose author's names begin with A.
 I have tried several maniipulations of where and select with select
 subqueries and I cannot get results from the queries.
 For example
 SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
 LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id =
 c.bookID snip
 Not really a php question :P

 You don't need a subquery for this. You can join all of the tables
 together and just use the where clause to cut down your results, but
 I'll give an example of both.

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId)
 inner join authors a on (a.id=c.authorId)
 where
 left(a.last_name = 'A');
 correct me if I'm wrong, but did you use the left() function
 in-correctly?

 The documentation shows a different way to use it then you describe.

 Something more like the following:

 WHERE
 LEFT(a.last_name, 1) = 'A';

 But that would be case-sensitive...

 So, something like this would work better IMHO

 WHERE
 UPPER(LEFT(a.last_name, 1)) = 'A';

 or

 WHERE
 a.last_name ILIKE 'A%';

 would do the trick
 or

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId)
 where
 c.authorId in (
 select id from authors where left(last_name='A')
 Again...

 SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')

 but yet again, case-sensitive...

 SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A')
 or
 SELECT id FROM authors WHERE last_name ILIKE 'A%'

 would do the trick

 );



 Thank you for the suggestions, gentlemen.
 As to the case sensitivity, since the authors' names must be written
 with the first letter in uppercase, even Anonymous or Unknown I
 assume I don't need to specify uppercase. Or does it really make a
 difference? Glad to learn of the option, though.

 I'm just starting on the listing of the books by author and just
 realized that the sorting should be by author (last name). Can I foresee
 a problem in that since the last_name is in associative tables and not
 in the book table? Or does the JOIN incorporate the last_name in the
 results?


-- 
unheralded genius: A clean desk is the sign of a dull mind. 
-
Phil Jourdan --- p...@ptahhotep.com
http://www.ptahhotep.com
http://www.chiccantine.com/andypantry.php

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP] formulate nested select

2009-03-31 Thread kyle.smith
What about using IN, something like:

SELECT * FROM book WHERE id IN (SELECT bookID FROM book_authors WHERE
authID IN (SELECT author.id FROM authors WHERE last_name LIKE
$Auth%));

You could use LEFT instead of LIKE, too.



 

-Original Message-
From: PJ [mailto:af.gour...@videotron.ca] 
Sent: Tuesday, March 31, 2009 2:06 PM
To: Jim Lucas
Cc: Chris; php-general@lists.php.net
Subject: Re: [PHP] formulate nested select

Gentlemen  all others,
The problem was partly fixed with ' ' around $Auth... but...
somehow, I see that the results do not work with the rest of the script.
The results give a an array within an array - so this mucks up all the
rest which is set up to deal with only the book table. The count() is
off as it shows the results_per_page setting and the pagination is off -
it shows 10 books but only displays 5 entries (from 5 arrays which, I
suppose is the reason for the coun() showing 10. The first page shows 5,
but the second indicates 7 books but displays only 6...
Now, I suppose that there are 2 ways to fix things:
1. Redo the rest of the script (a royal pain, I suspect) or 2. SELECT
only the books that are attributed to the targeted authors - which is
what I wanted to do in the first place. Something like:

$SQL = SELECT * FROM book b
WHERE b.id = (SELECT book_author.bookID WHERE book_author.authID
= (SELECT author.id WHERE LEFT(author.last_name, 1 ) = '$Auth');

I want to avoid joins as that seems to screw up the rest of the code
which is in an include page that needs to be repeated as long as there
are letters in the alphabet.
I'll try to figure something out, but as somebody not too optimistic
once said: it sure don't look too good (American, I believe...) :-)
 Jim Lucas wrote:
 Chris wrote:
 PJ wrote:
 I cannot find anything on google or the manuals/tutorials that 
 gives some kin of clear explanation of how to so nested selects 
 with where or whatever.
 I have three tables: books, authors and book-authors.
 I need to retrieve only those books whose author's names begin with
A.
 I have tried several maniipulations of where and select with select

 subqueries and I cannot get results from the queries.
 For example
 SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE 
 LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id

 = c.bookID snip
 Not really a php question :P

 You don't need a subquery for this. You can join all of the tables 
 together and just use the where clause to cut down your results, but

 I'll give an example of both.

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId) inner join 
 authors a on (a.id=c.authorId) where left(a.last_name = 'A');
 correct me if I'm wrong, but did you use the left() function 
 in-correctly?

 The documentation shows a different way to use it then you describe.

 Something more like the following:

 WHERE
 LEFT(a.last_name, 1) = 'A';

 But that would be case-sensitive...

 So, something like this would work better IMHO

 WHERE
 UPPER(LEFT(a.last_name, 1)) = 'A';

 or

 WHERE
 a.last_name ILIKE 'A%';

 would do the trick
 or

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId) where 
 c.authorId in ( select id from authors where left(last_name='A')
 Again...

 SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')

 but yet again, case-sensitive...

 SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A') or 
 SELECT id FROM authors WHERE last_name ILIKE 'A%'

 would do the trick

 );



 Thank you for the suggestions, gentlemen.
 As to the case sensitivity, since the authors' names must be written 
 with the first letter in uppercase, even Anonymous or Unknown I 
 assume I don't need to specify uppercase. Or does it really make a 
 difference? Glad to learn of the option, though.

 I'm just starting on the listing of the books by author and just 
 realized that the sorting should be by author (last name). Can I 
 foresee a problem in that since the last_name is in associative tables

 and not in the book table? Or does the JOIN incorporate the last_name 
 in the results?


--
unheralded genius: A clean desk is the sign of a dull mind. 
-
Phil Jourdan --- p...@ptahhotep.com
http://www.ptahhotep.com
http://www.chiccantine.com/andypantry.php

--
PHP General Mailing List (http://www.php.net/) To unsubscribe, visit:
http://www.php.net/unsub.php


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-31 Thread PJ
kyle.smith wrote:
 What about using IN, something like:

 SELECT * FROM book WHERE id IN (SELECT bookID FROM book_authors WHERE
 authID IN (SELECT author.id FROM authors WHERE last_name LIKE
 $Auth%));

 You could use LEFT instead of LIKE, too.
Well, I learned something here... but that also revealed another,
hidden, problem which I had not considered - the order by clause which I
had stupidly not included in my example:

$SQL = SELECT * FROM book
WHERE id IN (SELECT bookID
FROM book_author WHERE authID IN (SELECT author.id
FROM author WHERE LEFT(last_name, 1 ) = '$Auth'))
ORDER BY $sort $dir
LIMIT $offset, $records_per_page ;

I now realize that to keep things as simple as possible in the rest of
the code, I must join 1 column to the query result and that is last_name
from the author table.
the spelling, column and table names are spelled correctly. Without the
ORDER BY I get the right results. I'll try to JOIN the author table ???
But I see that I may be trying to do too much - I thought of showing how
many books were listed under each letter of the alphabet but I don't see
how it can be done in any simiple way as it would mean that I would have
to do the select once with the ORDER BY and a second time without it
just to get the number of listing. If there are a lot of books, like
thousands, it might slow down things.
I suppose I could live with ORDER BY title as that does not require
another effort.
Any thoughts or suggestions?





 -Original Message-
 From: PJ [mailto:af.gour...@videotron.ca]
 Sent: Tuesday, March 31, 2009 2:06 PM
 To: Jim Lucas
 Cc: Chris; php-general@lists.php.net
 Subject: Re: [PHP] formulate nested select

 Gentlemen  all others,
 The problem was partly fixed with ' ' around $Auth... but...
 somehow, I see that the results do not work with the rest of the script.
 The results give a an array within an array - so this mucks up all the
 rest which is set up to deal with only the book table. The count() is
 off as it shows the results_per_page setting and the pagination is off -
 it shows 10 books but only displays 5 entries (from 5 arrays which, I
 suppose is the reason for the coun() showing 10. The first page shows 5,
 but the second indicates 7 books but displays only 6...
 Now, I suppose that there are 2 ways to fix things:
 1. Redo the rest of the script (a royal pain, I suspect) or 2. SELECT
 only the books that are attributed to the targeted authors - which is
 what I wanted to do in the first place. Something like:

 $SQL = SELECT * FROM book b
 WHERE b.id = (SELECT book_author.bookID WHERE book_author.authID
 = (SELECT author.id WHERE LEFT(author.last_name, 1 ) = '$Auth');

 I want to avoid joins as that seems to screw up the rest of the code
 which is in an include page that needs to be repeated as long as there
 are letters in the alphabet.
 I'll try to figure something out, but as somebody not too optimistic
 once said: it sure don't look too good (American, I believe...) :-)
 Jim Lucas wrote:
 Chris wrote:
 PJ wrote:
 I cannot find anything on google or the manuals/tutorials that
 gives some kin of clear explanation of how to so nested selects
 with where or whatever.
 I have three tables: books, authors and book-authors.
 I need to retrieve only those books whose author's names begin with
 A.
 I have tried several maniipulations of where and select with select

 subqueries and I cannot get results from the queries.
 For example
 SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
 LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id

 = c.bookID snip
 Not really a php question :P

 You don't need a subquery for this. You can join all of the tables
 together and just use the where clause to cut down your results, but

 I'll give an example of both.

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId) inner join
 authors a on (a.id=c.authorId) where left(a.last_name = 'A');
 correct me if I'm wrong, but did you use the left() function
 in-correctly?

 The documentation shows a different way to use it then you describe.

 Something more like the following:

 WHERE
 LEFT(a.last_name, 1) = 'A';

 But that would be case-sensitive...

 So, something like this would work better IMHO

 WHERE
 UPPER(LEFT(a.last_name, 1)) = 'A';

 or

 WHERE
 a.last_name ILIKE 'A%';

 would do the trick
 or

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId) where
 c.authorId in ( select id from authors where left(last_name='A')
 Again...

 SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')

 but yet again, case-sensitive...

 SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A') or
 SELECT id FROM authors WHERE last_name ILIKE 'A%'

 would do the trick

 );


 Thank you for the suggestions, gentlemen.
 As to the case sensitivity, since the authors' names must be written
 with the first letter in uppercase, even Anonymous or Unknown I
 assume I don't need to specify

Re: [PHP] formulate nested select

2009-03-31 Thread haliphax
On Tue, Mar 31, 2009 at 5:15 PM, PJ af.gour...@videotron.ca wrote:
 kyle.smith wrote:
 What about using IN, something like:

 SELECT * FROM book WHERE id IN (SELECT bookID FROM book_authors WHERE
 authID IN (SELECT author.id FROM authors WHERE last_name LIKE
 $Auth%));

 You could use LEFT instead of LIKE, too.
 Well, I learned something here... but that also revealed another,
 hidden, problem which I had not considered - the order by clause which I
 had stupidly not included in my example:

 $SQL = SELECT * FROM book
        WHERE id IN (SELECT bookID
        FROM book_author WHERE authID IN (SELECT author.id
        FROM author WHERE LEFT(last_name, 1 ) = '$Auth'))
        ORDER BY $sort $dir
        LIMIT $offset, $records_per_page ;

 I now realize that to keep things as simple as possible in the rest of
 the code, I must join 1 column to the query result and that is last_name
 from the author table.
 the spelling, column and table names are spelled correctly. Without the
 ORDER BY I get the right results. I'll try to JOIN the author table ???
 But I see that I may be trying to do too much - I thought of showing how
 many books were listed under each letter of the alphabet but I don't see
 how it can be done in any simiple way as it would mean that I would have
 to do the select once with the ORDER BY and a second time without it
 just to get the number of listing. If there are a lot of books, like
 thousands, it might slow down things.
 I suppose I could live with ORDER BY title as that does not require
 another effort.
 Any thoughts or suggestions?





 -Original Message-
 From: PJ [mailto:af.gour...@videotron.ca]
 Sent: Tuesday, March 31, 2009 2:06 PM
 To: Jim Lucas
 Cc: Chris; php-general@lists.php.net
 Subject: Re: [PHP] formulate nested select

 Gentlemen  all others,
 The problem was partly fixed with ' ' around $Auth... but...
 somehow, I see that the results do not work with the rest of the script.
 The results give a an array within an array - so this mucks up all the
 rest which is set up to deal with only the book table. The count() is
 off as it shows the results_per_page setting and the pagination is off -
 it shows 10 books but only displays 5 entries (from 5 arrays which, I
 suppose is the reason for the coun() showing 10. The first page shows 5,
 but the second indicates 7 books but displays only 6...
 Now, I suppose that there are 2 ways to fix things:
 1. Redo the rest of the script (a royal pain, I suspect) or 2. SELECT
 only the books that are attributed to the targeted authors - which is
 what I wanted to do in the first place. Something like:

 $SQL = SELECT * FROM book b
 WHERE b.id = (SELECT book_author.bookID WHERE book_author.authID
 = (SELECT author.id WHERE LEFT(author.last_name, 1 ) = '$Auth');

 I want to avoid joins as that seems to screw up the rest of the code
 which is in an include page that needs to be repeated as long as there
 are letters in the alphabet.
 I'll try to figure something out, but as somebody not too optimistic
 once said: it sure don't look too good (American, I believe...) :-)
 Jim Lucas wrote:
 Chris wrote:
 PJ wrote:
 I cannot find anything on google or the manuals/tutorials that
 gives some kin of clear explanation of how to so nested selects
 with where or whatever.
 I have three tables: books, authors and book-authors.
 I need to retrieve only those books whose author's names begin with
 A.
 I have tried several maniipulations of where and select with select

 subqueries and I cannot get results from the queries.
 For example
 SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
 LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id

 = c.bookID snip
 Not really a php question :P

 You don't need a subquery for this. You can join all of the tables
 together and just use the where clause to cut down your results, but

 I'll give an example of both.

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId) inner join
 authors a on (a.id=c.authorId) where left(a.last_name = 'A');
 correct me if I'm wrong, but did you use the left() function
 in-correctly?

 The documentation shows a different way to use it then you describe.

 Something more like the following:

 WHERE
 LEFT(a.last_name, 1) = 'A';

 But that would be case-sensitive...

 So, something like this would work better IMHO

 WHERE
 UPPER(LEFT(a.last_name, 1)) = 'A';

 or

 WHERE
 a.last_name ILIKE 'A%';

 would do the trick
 or

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId) where
 c.authorId in ( select id from authors where left(last_name='A')
 Again...

 SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')

 but yet again, case-sensitive...

 SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A') or
 SELECT id FROM authors WHERE last_name ILIKE 'A%'

 would do the trick

 );


 Thank you for the suggestions, gentlemen.
 As to the case sensitivity, since the authors' names must be written

Re: [PHP] formulate nested select

2009-03-31 Thread Chris

PJ wrote:

Ian wrote:

On 31 Mar 2009 at 9:08, PJ wrote:

  

I must be doing something wrong. Can't figure it out even though I've
been searching the manuals  tutorials, it still does not work. Here is
the exact code that I have tried; the first version is commented out and
obviously does not work either (the spelling, the table names and column
names are correct):

$books = array();
/*$SQL = SELECT * FROM book b
JOIN book_author c
ON b.id = c.bookID
JOIN author a ON a.id = c.authID
WHERE LEFT(a.last_name,1) = $Auth
ORDER BY $sort $dir
LIMIT $offset, $records_per_page; */

$SQL = SELECT * FROM book b
INNER JOIN book_author c
ON b.id = c.bookID
WHERE c.authID = (SELECT id FROM author a WHERE LEFT(a.last_name, 1
) = $Auth )


Hi,

I think this should be '$Auth' as MySQL will be expecting a string.
  

Hmmm That was it.  I'm not clear on this... what was MySQL getting?
if not a string...
sorry for my ignorance...


You have to quote strings in sql, only numbers (and booleans) don't have 
quotes.


ie

$sql = .. where left(a.last_name, 1) = ' . 
mysql_real_escape_string($Auth) . ';


single quotes around the value and it's properly escaped.

--
Postgresql  php tutorials
http://www.designmagick.com/


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-31 Thread PJ
haliphax wrote:
 On Tue, Mar 31, 2009 at 5:15 PM, PJ af.gour...@videotron.ca wrote:
 kyle.smith wrote:
 What about using IN, something like:

 SELECT * FROM book WHERE id IN (SELECT bookID FROM book_authors WHERE
 authID IN (SELECT author.id FROM authors WHERE last_name LIKE
 $Auth%));

 You could use LEFT instead of LIKE, too.
 Well, I learned something here... but that also revealed another,
 hidden, problem which I had not considered - the order by clause which I
 had stupidly not included in my example:

 $SQL = SELECT * FROM book
 Â  Â  Â  Â WHERE id IN (SELECT bookID
 Â  Â  Â  Â FROM book_author WHERE authID IN (SELECT author.id
 Â  Â  Â  Â FROM author WHERE LEFT(last_name, 1 ) = '$Auth'))
 Â  Â  Â  Â ORDER BY $sort $dir
 Â  Â  Â  Â LIMIT $offset, $records_per_page ;

 I now realize that to keep things as simple as possible in the rest of
 the code, I must join 1 column to the query result and that is last_name
 from the author table.
 the spelling, column and table names are spelled correctly. Without the
 ORDER BY I get the right results. I'll try to JOIN the author table ???
 But I see that I may be trying to do too much - I thought of showing how
 many books were listed under each letter of the alphabet but I don't see
 how it can be done in any simiple way as it would mean that I would have
 to do the select once with the ORDER BY and a second time without it
 just to get the number of listing. If there are a lot of books, like
 thousands, it might slow down things.
 I suppose I could live with ORDER BY title as that does not require
 another effort.
 Any thoughts or suggestions?




 -Original Message-
 From: PJ [mailto:af.gour...@videotron.ca]
 Sent: Tuesday, March 31, 2009 2:06 PM
 To: Jim Lucas
 Cc: Chris; php-general@lists.php.net
 Subject: Re: [PHP] formulate nested select

 Gentlemen  all others,
 The problem was partly fixed with ' ' around $Auth... but...
 somehow, I see that the results do not work with the rest of the script.
 The results give a an array within an array - so this mucks up all the
 rest which is set up to deal with only the book table. The count() is
 off as it shows the results_per_page setting and the pagination is off -
 it shows 10 books but only displays 5 entries (from 5 arrays which, I
 suppose is the reason for the coun() showing 10. The first page shows 5,
 but the second indicates 7 books but displays only 6...
 Now, I suppose that there are 2 ways to fix things:
 1. Redo the rest of the script (a royal pain, I suspect) or 2. SELECT
 only the books that are attributed to the targeted authors - which is
 what I wanted to do in the first place. Something like:

 $SQL = SELECT * FROM book b
 WHERE b.id = (SELECT book_author.bookID WHERE book_author.authID
 = (SELECT author.id WHERE LEFT(author.last_name, 1 ) = '$Auth');

 I want to avoid joins as that seems to screw up the rest of the code
 which is in an include page that needs to be repeated as long as there
 are letters in the alphabet.
 I'll try to figure something out, but as somebody not too optimistic
 once said: it sure don't look too good (American, I believe...) :-)
 Jim Lucas wrote:
 Chris wrote:
 PJ wrote:
 I cannot find anything on google or the manuals/tutorials that
 gives some kin of clear explanation of how to so nested selects
 with where or whatever.
 I have three tables: books, authors and book-authors.
 I need to retrieve only those books whose author's names begin with
 A.
 I have tried several maniipulations of where and select with select
 subqueries and I cannot get results from the queries.
 For example
 SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
 LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id
 = c.bookID snip
 Not really a php question :P

 You don't need a subquery for this. You can join all of the tables
 together and just use the where clause to cut down your results, but
 I'll give an example of both.

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId) inner join
 authors a on (a.id=c.authorId) where left(a.last_name = 'A');
 correct me if I'm wrong, but did you use the left() function
 in-correctly?

 The documentation shows a different way to use it then you describe.

 Something more like the following:

 WHERE
 LEFT(a.last_name, 1) = 'A';

 But that would be case-sensitive...

 So, something like this would work better IMHO

 WHERE
 UPPER(LEFT(a.last_name, 1)) = 'A';

 or

 WHERE
 a.last_name ILIKE 'A%';

 would do the trick
 or

 select *
 from
 books b inner join book_authors c on (b.id=c.bookId) where
 c.authorId in ( select id from authors where left(last_name='A')
 Again...

 SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')

 but yet again, case-sensitive...

 SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A') or
 SELECT id FROM authors WHERE last_name ILIKE 'A%'

 would do the trick

 );

 Thank you for the suggestions, gentlemen.
 As to the case sensitivity, since the authors

Re: [PHP] formulate nested select

2009-03-30 Thread Chris

PJ wrote:

I cannot find anything on google or the manuals/tutorials that gives
some kin of clear explanation of how to so nested selects with where or
whatever.
I have three tables: books, authors and book-authors.
I need to retrieve only those books whose author's names begin with A.
I have tried several maniipulations of where and select with select
subqueries and I cannot get results from the queries.
For example
SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id =
c.bookID snip


Not really a php question :P

You don't need a subquery for this. You can join all of the tables 
together and just use the where clause to cut down your results, but 
I'll give an example of both.


select *
from
  books b inner join book_authors c on (b.id=c.bookId)
  inner join authors a on (a.id=c.authorId)
where
  left(a.last_name = 'A');

or

select *
from
  books b inner join book_authors c on (b.id=c.bookId)
where
  c.authorId in (
select id from authors where left(last_name='A')
  );

--
Postgresql  php tutorials
http://www.designmagick.com/


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-30 Thread Jim Lucas

Chris wrote:

PJ wrote:

I cannot find anything on google or the manuals/tutorials that gives
some kin of clear explanation of how to so nested selects with where or
whatever.
I have three tables: books, authors and book-authors.
I need to retrieve only those books whose author's names begin with A.
I have tried several maniipulations of where and select with select
subqueries and I cannot get results from the queries.
For example
SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id =
c.bookID snip


Not really a php question :P

You don't need a subquery for this. You can join all of the tables 
together and just use the where clause to cut down your results, but 
I'll give an example of both.


select *
from
  books b inner join book_authors c on (b.id=c.bookId)
  inner join authors a on (a.id=c.authorId)
where
  left(a.last_name = 'A');


correct me if I'm wrong, but did you use the left() function in-correctly?

The documentation shows a different way to use it then you describe.

Something more like the following:

WHERE
   LEFT(a.last_name, 1) = 'A';

But that would be case-sensitive...

So, something like this would work better IMHO

WHERE
   UPPER(LEFT(a.last_name, 1)) = 'A';

or

WHERE
   a.last_name ILIKE 'A%';

would do the trick


or

select *
from
  books b inner join book_authors c on (b.id=c.bookId)
where
  c.authorId in (
select id from authors where left(last_name='A')


Again...

SELECT id FROM authors WHERE LEFT(last_name, 1) = 'A')

but yet again, case-sensitive...

SELECT id FROM authors WHERE UPPER(LEFT(last_name, 1)) = 'A')
or
SELECT id FROM authors WHERE last_name ILIKE 'A%'

would do the trick


  );





--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] formulate nested select

2009-03-30 Thread Chris

Jim Lucas wrote:

Chris wrote:

PJ wrote:

I cannot find anything on google or the manuals/tutorials that gives
some kin of clear explanation of how to so nested selects with where or
whatever.
I have three tables: books, authors and book-authors.
I need to retrieve only those books whose author's names begin with A.
I have tried several maniipulations of where and select with select
subqueries and I cannot get results from the queries.
For example
SELECT * FROM book b, book_authors c (SELECT id FROM author WHERE
LEFT(author.last_name = $Auth )) as a WHERE a.id = c.authID  b.id =
c.bookID snip


Not really a php question :P

You don't need a subquery for this. You can join all of the tables 
together and just use the where clause to cut down your results, but 
I'll give an example of both.


select *
from
  books b inner join book_authors c on (b.id=c.bookId)
  inner join authors a on (a.id=c.authorId)
where
  left(a.last_name = 'A');


correct me if I'm wrong, but did you use the left() function in-correctly?


Probably, I didn't look at the doco - I (stupidly I know) assumed it was 
correct in the original example.


Thanks for the correction.

--
Postgresql  php tutorials
http://www.designmagick.com/


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php