Join two mysql tables
I have two databases - one for articles and the another for the articles' meta information (Like author, date, category and atc.). I have the following columns in meta table: ID, article id, meta type and meta value. I wonder how can I join these two tables to get both - article and meta information - with one mysql query. The article id isn't unique in meta table, that is why I can't figure out how to acces开发者_StackOverflow中文版s specific meta type and according value for the article...
Here is the mysql I'm tried to use:
SELECT products.*, product_meta.meta_value
FROM products
LEFT JOIN product_meta ON products.ID = product_meta.product_id
but this query doesn't seem to be what I need. I there are for example two records in articles table and ten in meta table this code displays ten results instead of two:
$products = mysql_query("SELECT products.*, product_meta.meta_value
FROM products
LEFT JOIN product_meta ON products.ID = product_meta.product_id") or die(mysql_error());
while ($product = mysql_fetch_assoc($products)) {
echo $product["title"];
}
Can anyone please help?
try the following sql statements:
SELECT products.*, product_meta.meta_value
FROM products LEFT OUTER JOIN product_meta
ON products.ID = product_meta.product_id
WHERE product_meta.product_id NOT IS NULL
just change the LEFT JOIN
to a RIGHT JOIN
and you should get the results you want. or flip the query: SELECT ... FROM product_meta LEFT JOIN product .. etc.
"I have the following columns in meta table: ID, article id, meta type and meta value."
Are you sure this is an appropriate design? If an article can only ever have at most one author, date etc. then perhaps these should be columns in the "article" table. (On the other hand, it's quite possible to envisage an article being co-authored by several people - but then you would probably want an "article_authors" table specifically to list the authors of articles, rather than this Entity-Attribute-Value system you have going.)
If you're dead set on using this design, then you could:
1) Fetch the metadata for each article in one row, concatenated into a single field.
2) Just look for articles, and for each article run a query to get metadata from the "meta" table:
$products = mysql_query("SELECT products.*, product_meta.meta_value
FROM products
LEFT JOIN product_meta ON products.ID = product_meta.product_id") or die(mysql_error());
while ($product = mysql_fetch_assoc($products)) {
$products_meta = mysql_query( /* something else */ );
echo $product["title"];
}
3) Run the query you already have, but check at each row whether it's a new article, or just more metadata for the previous article:
$products = mysql_query("SELECT products.*, product_meta.meta_value
FROM products
LEFT JOIN product_meta ON products.ID = product_meta.product_id") or die(mysql_error());
$old_product_id = -1;
while ($product = mysql_fetch_assoc($products)) {
if ( $product['product_id'] != $old_product_id ) {
$old_product_id = $product['product_id'];
echo $product["title"];
}
}
Check out Jeff's guide to SQL joins for some help figuring out which join might be best for your purposes.
Use subqueries:
SELECT products.*, (SELECT product_meta.meta_value FROM product_meta WHERE
products.ID = product_meta.product_id AND meta_type = "author") AS meta_author
FROM products
You can add more subqueries to add more meta_types toe the resultset.
But beware that subqueries don't offer optimal performance. If the mysql performance is important, you could consider using your current join statement and transpose the data in php.
I'd also question the database design as a starter - it strikes me that some 'meta types' (Author, Category) should be separate tables, while others (Date) should live in the article table. Database normalisation is the key, and there's a great intro on the MySQL site: http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html
When it comes to joining tables, you might prefer to use something like:
SELECT
products.*, product_meta.meta_value
FROM
products, product_meta
WHERE
products.ID = product_meta.product_id
AND product_meta.meta_type = 'author';
ie. listing the tables in the from clause instead of using a join
Then again, for the purpose of simply returning the relevant meta rows, it may be that all you need to do is add a 'WHERE' clause to your existing query:
... WHERE product_meta.meta_type = 'author';
精彩评论