Getting Labels of id's - php

What is the best way to get labels of id's .
Here is the problem i'm facing .
I have a many tables that only contains id's (subject_id , level_id , place_id , etc..)
What is the best way to display the labels of those id's without making a complex sql query when displaying (have minimum of 6'ids) ?
The other options which is not very nice to do would be to call get_label(id,table,lang)
but of course you can see the problem for each column (Total queries = column * rows)
Any better solution or i'm stuck without doing the join on 6 tables ?
If it's helps i'm using kohana
here is what i have ...
and the subject table for the subject_id :
I have for every field_id a table that correspond .
In term of performance which is better making a join or just calling a query to get the specific label when needed . ?

You want to use a SQL JOIN for this.
SELECT t1.*, t2.subject_en, ...
FROM table1 t1
JOIN table2 t2 ON (t2.id = t1.subject_id)
A JOIN has a much better performane - you have only a single query which can be properly optimized by the database engine while doing a SELECT while iterating over the rows from the initial query would give you n+1 separate queries.

Related

Combining Two Select Queries MySQL

I have two tables : items and comments.
I want to select all items which a user commented on.
For simplicity, lets assume the items table has two columns : item_id and item_content. Let the comments table have 3 columns user_id, item_id and comment_content.
I am given the user_id of the commenting user, I need to first select all the item_id from the comments table, where user_id = myUserId.
This is a basic query SELECT item_id FROM comments WHERE user_id = '$myUserId'.
Then I need to select the item_content for each item_id returned by the previous query.
I was thinking of doing a while($row = $my_first_query->fetch_array()) loop, and inside of it doing something like SELECT item_content FROM item WHERE item_id = $row["item_id"]
however this is a bit messy and I was wondering if there was a simpler way of doing this, by combining the two queries into one.
Use an INNER JOIN:
SELECT t1.*
FROM items t1
INNER JOIN comments t2
ON t1.item_id = t2.item_id
WHERE t2.user_id = myUserId
The approach you suggested of first querying the comments table and then looping over the result set is inefficient. In a join, MySQL can handle this algebra much faster than your PHP code.
Depending of what you want to do exactly, you can just use a JOIN clause. The "header" table info will be found within all rows, so it might not be what you want to do.
Another way would be to run two distinct queries, the first one unchanged and the second one with a join. You would then have one result with the header, and the other with all the details that you could go through. It's more performant than run the same query over and over network wise.

Mysql query exicution time is too slow

SELECT * FROM articles t LEFT OUTER JOIN category_type category ON (t.category_id=category.id)
WHERE (t.status = 6 AND t.publish_on <= '2014-02-14' AND t.id NOT IN (13112,9490,9386,6045,1581,1034,991,933,879,758) AND t.category_id IN (14)) ORDER BY t.id DESC LIMIT 7;
It take more then 1.5 second to execute this query.
Can you give me some idea ? How can I improve this query and minimum execution time ?
First thing => use where instead of inner join. Because where is faster than inner join query.
Second thing => use indexes for the frequently searched columns. As in your example you search on the basis of status, publish_on besides id as primary index.
If you are using mysql then you can try propose table structure option in the phpmyadmin which can help you to decide valid data types for your column names. This could help you to optimize your query processing.
query processing time depends on many things like: database server load, amount of data in the table and the data types used for the column names too.
why join it with category table?, the category table is not in the where clause nor in the select column clause, so why add it in the query?
oops, * was used, so it "is" in the category table
apologies

search query slow, recordset based on view. how to speed it up?

I have a recordset based on a view in MySQL that I use to return search results but it is painfuilly slow (consistently 21 seconds!). A similar search in the same environment takes under a second.
I fear that it is the view that is slowing things down since I have four left joins and one subquery in there to make related data available in the search.
Is there any general guidance for speeding up a query when using a view? I have researched indexing but it seems that is not allowed in MySQL in views.
Thanks in advance for any suggestions.
The code to create my view:
CREATE VIEW vproducts2 AS
SELECT products2.productid, products2.active, products2.brandid,
products2.createddate, products2.description, products2.inventorynum,
products2.onhold, products2.price, products2.refmodnum, products2.retail,
products2.sefurl, products2.series, products2.sold,
`producttype`.`type` AS type, categories.category AS category,
`watchbrands`.`brand` AS brand, productfeatures.productfeaturevalue AS size,
(SELECT productimages.image
FROM productimages
WHERE productimages.productid = products2.productid
LIMIT 1
) AS pimage
FROM products2
LEFT JOIN producttype ON producttype.typeid = products2.typeid
LEFT JOIN categories ON categories.categoryid = products2.categoryid
LEFT JOIN watchbrands ON watchbrands.brandid = products2.brandid
LEFT JOIN productfeatures ON productfeatures.productid = products2.productid
AND productfeatures.featureid = 1
You need to ensure that you have indexes on the underlying tables, not on the view. The view should use such tables.
The first index that screams out is on productimages(productid, productimage). This will speed up the subquery in the select clause.
You should also have primary key indexes for what look like primary keys on all the tables . . . categories(categoryid), producttype(typeid), watchbrands(brandid), and (I think) productfeatures(productid, featureid).

Mysql Query to check 3 tables for an existing row

What I want to do is to query three separate tables into one row which is identified by a unique reference. I don't really have full understanding of the Join clause as it seems to require some sort of related data from each table.
I know I can go about this the long way round, but can not afford to lose even a little efficiency. Any help would be greatly appreciated.
Table Structure
package_id int(8),
client_id int(8),
unique reference varchar (40)
Each of the tables have essentially the same structure. I just need to know how to query all three, for 1 row.
If you have few tables that are sharing the same or similar definition, you can use union or union all to treat them as one. This query will return rows from each table having requested reference. I've included OriginTable info in case your code will need to refer to original table for update or something else.
select 'TableA' OriginTable,
package_id,
client_id
from TableA
where reference = ?
union all
select 'TableB' OriginTable,
package_id,
client_id
from TableB
where reference = ?
union all
select 'TableC' OriginTable,
package_id,
client_id
from TableC
where reference = ?
You might extend select list with other columns, provided that they have the same data type, or are implicitly convertible to data type from first select.
Let's say you have 3 tables :
table1, table2 and table3 with structure
package_id int(8),
client_id int(8),
unique reference varchar (40)
Let's assume that column reference is unique key.
Then you can use this:
SELECT t1.exists_row ,t2.exists_row ,t3.exists_row FROM
(
(SELECT COUNT(1) as exists_row FROM table1 t1 WHERE
t1.reference = #reference ) t1,
(SELECT COUNT(1) as exists_row FROM table1 t2 WHERE
t2.reference = #reference ) t2,
(SELECT COUNT(1) as exists_row FROM table1 t3 WHERE
t3.reference = #reference ) t3
) a
;
Replace #reference with actual value of unique key
or when you provide output of
SHOW CREATE TABLE
I can rewrite SQL with actual query
It is entirely possible to create a join between tables using a where clause. In fact this is often what I do as I find it leads to clearer information of what you are actually doing, and if you don't get the results you expect you can debug it bit by bit.
That said however a join is certainly a lot quicker to write!
Please bear in mind I'm a bi rusty on SQL so I may have missed remembered, and I'm not going to include any code as you haven't said what DBMS you are using as they all have slightly different code.
The thing to remember is that the join functions on a column with the same data (and type) within it.
It is much easier if each table has the 'joining' field named the same, then it should be a matter of
join on <nameOfField>
However if you wish to use field that have different names in the different tables you will need to list the fully qualified names. ie tableName.FieldName
If you are having trouble with natural, inner and outer, left and right, you need to think of a venn diagram with the natural being the point of commonality between the tables. If you are using only 2 tables inner and outer are equivalent to left and right (with each table being a single circle in the venn diagram) and left and right being the order of the tables in your list in the main part of your select (the first being the left and the second being the right).
When you add a third table this is where you can select any of the cross over section using these keywords.
Again however I have always found it easier to do a primary select and create a temp table, then perform my next join using this temp table (so effectively only need to use natural or left and right again). Again I find this easier to debug.
The best thing is to experiment and see what you get in return. Without a diagram of your tables this is the best I can offer.
in brief...
nested selects where field = (select from table where field = )
and temp tables
are (I think) easier to debug... but do take more writting !
David.
array_of_tables[]; // contain name of each table
foreach(array_of_tables as $val)
{
$query="select * from `$val` where $condition "; // $conditon
$result=mysqli_query($connection,$query);
$result_row[]=mysqli_fetch_assoc($result); // if only one row going to return form each table
//check resulting array ,for your row
}
SELECT * FROM table1 t1 JOIN table2 t2 ON (t2.unique = t1.unique) JOIN table3 t3 ON (t3.unique = t1.unique) WHERE t1.unique = '?';
You could use a JOIN like this, assuming all three tables have the same unique column.

PHP MySql query 2 tables that have no common attributes at the same time?

I am trying to query 2 tables in a database, each query having nothing to do with each other, other then being on the same page.
Query 1 - The first query on the page will retrieve text and images that are found throughout the page from Table A.
Query 2 - The second query will retrieve several products with a image, description and title for each product from Table B.
I know that putting the second query inside the first query's while loop would work but of course is very inefficient.
How can I and what is the best way to retrieve all the data I need through 1 query?
Thanks,
Dane
So all you want to know is if its ok to have 2 queries on the same webpage? Its A-OK. Go right ahead. Its completelly normal. No one expects a join between table news and table products. Its normal to usetwo queries to fetch data from two unrelated tables.
Use LEFT or INNER JOIN (depends on whether you want to display records from TableA that have no correspondent records in TableB)
SELECT a.*, b.*
FROM TableA a
[LEFT or INNER] JOIN TableB b ON (b.a_id = a.id)
If there's no way to relate the two tables to each other, then you can't use a JOIN to grab records from both. You COULD use a UNION query, but that presumes that you can match up fields from each table, as a UNION requires you to select the same number/type of fields from each table.
SELECT 'pageinfo' AS sourcetable, page.id, page.images, page.this, page.that
WHERE page.id = $id
UNION
SELECT 'product' AS sourcetable, products.id, products.image, product.other, product.stuff
But this is highly ugly. You're still forcing the DB server to do two queries in the background plus the extra work of combining them into a single result set, and then you have to do extra work to dis-entangle in your code to boot.
It's MUCH easier, conceptually and maintenance-wise, to do two seperate queries instead.

Categories