match against mysql query against multiple tables with the same fields - php

Current query:
select * from `table1` where MATCH (`product_name`) AGAINST ('test' IN BOOLEAN MODE) AND `price` BETWEEN 0 AND 1000 order by MATCH (`product_name`) AGAINST ('test' IN BOOLEAN MODE) desc, `price` DESC LIMIT 0, 30
How can I run the above query on multiple tables with the same fields? eg table2, table3, table4
Would the query be faster if I were to combine all the data from all tables into 1 single table instead of multiple tables? Or would it make no difference at all?

Answer to 1st question : You can use JOINS in MySQL,that combines table as you say.
Answer to 2nd question :
One way :
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1, table2
WHERE
table1.foreignkey = table2.primarykey
AND (some other conditions)
Second way :
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1 INNER JOIN table2
ON table1.foreignkey = table2.primarykey
WHERE
(some other conditions)
The WHERE syntax is more relational model oriented where INNER JOIN is ANSI syntax which you should use.
The first query using WHERE become much much more confusing, hard to read, and hard to maintain once you need to start adding more tables to your query. Imagine doing that same query and type of join on four or five different tables ... it's a nightmare.
However, depending on the query optimizer, they may have the same meaning to the machine.
You should always code to be readable.
That is to say, if this is a built-in relationship, use the explicit join. if you are matching on weakly related data, use the where clause on the result set obtained from JOINS.
Hope this helps

Related

Selecting Data from internally connected Tables in Mysql?

Suppose I have two tables which are joined with each other,
I need to select data from them without using Join syntax. Is that practically possible?
If yes, Then How?
Thanks in Advance
vJ
Yes, it is. And it is perfectly valid.
SELECT tblOne.value1,tblTwo.value2 FROM tblOne,tblTwo WHERE tblOne.c1=tblTwo.c2
Use Unions.
Its syntax like-
SELECT a,b,c FROM table1
UNION
SELECT d,e,f FROM table2
UNION ALL will return all rows from both tables, if you only want DISTINCT rows then you will want to use UNION
Use two separate queries. Each query references one table.
The tables in the database aren't really "joined". There may be foreign key constraints defined, or the rows may be related by values stored in each table... but they aren't "joined".
A JOIN operation is the mechanism the relational database engine uses to match rows (using an algorithm, either nested loops, merge, or hash.)
The JOIN keyword is the ANSI standard for specifying that the database perform a join operation.
The old-school comma operator is an alternative to the JOIN keyword, but it's still a join operation.

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

MySQL joining tables with join

I've been scratching my head at this problem all day and I simple just can't work it out. This is the first time I've attempted to try and use SQL Joining, while we do kinda get taught the basics I'm more into pushing a little more into the advanced stuff.
Basically I'm making my own forum, and I have two tables. f_topics (The threads) and f_groups (The forums, or categories). There is a relationship between topicBase in f_topics and groupID in f_groups, this shows which group each topic belongs to. Each topic has a unique ID called topicID and same for the groups, called groupID.
Basically, I'm trying to get all these columns into a single SELECT statement - The title of the topic, the date the topic was posted, the ID of the group the topic belongs in, and the name of that group. This is what I was trying to use, but the group always comes back as 1, even if the topic is in groupID 2:
$query=mysqli_query($link, "
SELECT `topicName`, `topicDate`, `groupName`, `groupID`
FROM `f_topics`
NATURAL JOIN `f_groups`
WHERE `f_topics`.`topicID`='$tid';
") or die("Failed to get topic detail E: ".mysqli_error());
var_dump(mysqli_fetch_assoc($query));
Sorry if this doesn't make much sense, and if my entire logic is completely wrong, if so could you suggest an alternate method?
Thanks for reading!
To join tables, you need to map the foreign keys. Assuming your groups table has an groupID field, this is how you'd join them:
SELECT `topicName`, `topicDate`, `groupName`, `groupID`
FROM `f_topics`
LEFT JOIN `f_groups`
ON `f_topics`.`groupID` = `f_groups`.`groupID`
WHERE`f_topics`.`topicID`='$tid';
So from what I gather there is a column in f_topics named "topicBase" which references the groupID column from the f_groups table.
Based on that assumption, you can perform either an INNER JOIN or a LEFT JOIN. INNER requires there be an entry in both tables while LEFT requires there only be data in f_topics.
SELECT
f_topics.topicName,
f_topics.topicDate
f_groups.groupName
f_groups.groupID
FROM
f_topics
INNER JOIN
f_groups
ON
f_topics.topicBase = f_groups.groupID
WHERE
f_topics.topicID = '$tid'
I recommend you avoid NATURAL JOIN.
Primarily because a working query can be broken by the addition of a new column in a referenced table, which matches a column name in the other referenced table.
Secondly, for any reader (reviewer) of the SQL, which columns are being matched to which columns is not clear, without a careful review of both tables. (And, if someone has added a column that has broken the query, it makes it even more difficult to figure out what the JOIN criteria used to be, before the column was added.
Instead, I recommend you specify the column names in a predicate in the ON clause.
It's also good practice to qualify all column references by table name, or preferably, a shorter table alias.
For simpler statements, I agree that this may look like unnecessary overhead. But once statements become more complicated, this pattern VASTLY improves the readability of the statement.
Absent the definitions of the two tables, I'm going to have to make assumptions, and I "guess" that there is a groupID column in both of those tables, and that is the only column that is named the same. But you specify that its the topicBase column in f_topics that matches groupID in f_groups. (And the NATURAL JOIN won't get you that.)
I think the resultset you want will be returned by this query:
SELECT t.`topicName`
, t.`topicDate`
, g.`groupName`
, g.`groupID`
FROM `f_topics` t
JOIN `f_groups` g
ON g.`groupID` = t.`topicBase`
WHERE t.`topicID`='$tid';
If its possible for the topicBase column to be NULL or to contain a value that does not match a f_groups.GroupID value, and you want that topic returned, with the columns from f_group returned as NULL (when there is no match), you can get that with an outer join.
To get that behavior, in the query above, add the LEFT keyword immediately before the JOIN keyword.

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.

MySQL query to eliminate the use of this PHP code

I have one query that INNER JOINs Table A with Table B and Table C, and I have another query that INNER JOINs Table A with Table D. I could achieve what I want to do by merging the 2 results, removing duplicates and ordering them in PHP code, but I want to know if MySQL has this functionality, I also think it'd be faster and easier to code once I understand it. Essentially, I want to have the results from Query 1 OR from Query 2. Perhaps the following will help:
Query 1:
SELECT pkAssociation, associations.strNameEn, associations.strNameFr
FROM associations
INNER JOIN eventassociations ON fkAssociation = pkAssociation
INNER JOIN events on fkEvent = pkEvent
WHERE events.enumDeleted = 'no'
GROUP BY pkAssociation
Query 2:
SELECT pkAssociation, associations.strNameEn, associations.strNameFr
FROM associations
INNER JOIN associationprograms AS aprogs ON aprogs.fkAssociation = associations.pkAssociation
GROUP by pkAssociation
The tables don't have anything else of relevance that don't show up in the query. I'm sorry if I'm not asking this correctly, I don't even know how to ask a question about this properly. If the column names or sample data is needed, then I can provide some. Sorry for the inconvenience and long post.
You want the UNION DISTINCT statement, placed between the two queries. This will combine the result sets from both and remove duplicates. You can then place your ORDER BY clause after all UNIONS (if you have one).
For example:
SELECT col1, col2 FROM tableA
UNION DISTINCT
SELECT col1, col2 FROM tableB
ORDER BY col2 DESC

Categories