I have two different databases and I have to run a query where I am going to join tables from both databases in a single query. My query goes like this:
SELECT mm.* FROM tbl1 mm INNER JOIN tbl2 t ON mm.module_id=t.module_id WHERE mm.module_name NOT IN(SELECT module_name FROM tbl3)"
Here tbl1 and tbl2 are in one database and tbl3 is in the second database. Is it possible to run this query without HARD CODING the database names before the table names? I created common files global_config1.php and global_config2.php which have the database constants and other php database connection constants and am using require_once(global_config1.php) and require_once(global_config2.php) but the query fails.
Try this:
SELECT Database1.TableA.ColumnA1, Database1.TableA.ColumnA2,
Database2.TableB.ColumnB1, Database2.TableB.ColumnB2
FROM Database1.TableA
INNER JOIN
Database2.TableB ON
Database1.TableA.ColumnA3 = Database2.TableB.ColumnB3
Now, you will see the complete result in a single row. In case, the column names are same in both databases, you will see the column names same in the result and it will be impossible to get the value in PHP because 2 or more column name is same. To accomplish this, lets write another query
you can use two different database to fetch a record, for this you have two database object.
try this,
<?php
$con = mysqli_connect("localhost","root","","test");
$con1 = mysqli_connect("localhost","root","","test1");
$query = "SELECT mm.* FROM test.tbl1 mm INNER JOIN test.tbl2 t ON mm.module_id=t.module_id WHERE mm.module_name NOT IN(SELECT module_name FROM test1.tbl3)"
?>
For CI
$query = $this ->db->query("SELECT * FROM Table-1 WHERE id = (SELECT qid FROM Table-2 where post_status ='active' AND post_type= 'quick') ");
return $query->result_array();
My purpose was resolved by separating the queries and the database connection string variables. So to run a query on one database, I entered separate connection string variables in mysql_query(). This helped fetch the data from both databases.
Related
I'm getting a weird result from a quite long query, which I will simplify here:
DROP TEMPORARY TABLE IF EXISTS table1;
CREATE TEMPORARY TABLE table1 AS
(SELECT
parent.id as parent_id,
times.a_time,
times.sequence,
FROM times
LEFT JOIN parent ON times.parent_id=parent.id
WHERE times.stop_id=10);
DROP TEMPORARY TABLE IF EXISTS table2;
CREATE TEMPORARY TABLE table2 AS
(SELECT
parent.id as parent_id,
times.b_time,
times.sequence,
FROM times
LEFT JOIN parent ON times.parent_id=parent.id
WHERE times.stop_id=15 );
--here comes PDO->exec();
SELECT table1.*, table2.b_time
FROM table1
LEFT JOIN table2 ON table1.parent_id=table2.parent_id
WHERE table2.parent_id IS NOT NULL AND table1.sequence<table2.sequence
ORDER BY table1.a_time
I'm testing the query using EMS MySQL Manager 2007, and in PHP I'm using PDO query.
In order to get the final result, (I know that PDO doesn't support running this full query at once and giving back the result set), I run PDO->exec() after temporary tables creation (see comment in the query), and then I run PDO->query() on the last SELECT:
$db = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME, DB_USER, DB_PASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$tempTablesSQL='DROP TEMPORARY TABLE IF EXISTS...'; //create temporary tables
$db->exec($tempTablesSQL);
$sql='SELECT table1.*, table2.b_time ...'; //JOIN and SELECT the results
$results=array();
foreach($db->query($sql) as $row){
$results[]=$row;
}
print_r($results);
In MySQL Manager I run the whole query at once, and for those specific IDs I'm getting 29 rows as result (which is correct, because the records are inserted from a previously parsed file, and by comparing the results to the file I know they are good).
But in PHP, I'm getting only 25 results, and totally wrong values for b_time.
So, my questions are:
why do I get wrong results?
is my approach of calling this query wrong (in PHP)?
Any help is appreciated.
--EDIT--
It's not just PDO, I tried with mysqli_multi_query, I'm getting the same wrong results.
One important thing I noticed is: if I use regular tables instead of the temporary, the results are fine.
Let my try to put a couple of suggestions on the second part of your question which is is my approach of calling this query wrong?
First of all it looks like you don't need to create any temp tables. Based on what you showed the whole thing can be a single query like
SELECT q1.parent_id, q1.a_time, q1.sequence, q2.b_time
FROM
(
SELECT p.id parent_id, t.a_time, t.sequence
FROM times t LEFT JOIN parent p
ON t.parent_id=p.id
WHERE t.stop_id = ?
) q1 LEFT JOIN
(
SELECT p.id as parent_id, t.b_time, t.sequence
FROM times t LEFT JOIN parent p
ON t.parent_id=parent.id
WHERE t.stop_id = ?
) q2 ON q2.parent_id IS NOT NULL
AND q1.sequence < q2.sequence
ORDER BY q1.a_time
And execute it as a prepared statement
...
$sql = 'SELECT ...'; // the whole thing from above
$query = $db->prepare($sql);
$query->execute(array($stop_id1, $stop_id2));
$result = $query->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
Now even if for some reason you have to use temp tables and perform some manipulations along the way before returning the result set then I'd suggest to wrap it up a stored procedure
DELIMITER $$
CREATE PROCEDURE sp_myproc (IN stop_id1 INT, IN stop_id2 INT, ...)
BEGIN
DROP TEMPORARY TABLE IF EXISTS table1;
CREATE TEMPORARY TABLE table1 AS
...
WHERE times.stop_id = stop_id1;
DROP TEMPORARY TABLE IF EXISTS table1;
CREATE TEMPORARY TABLE table1 AS
...
WHERE times.stop_id = stop_id2
-- return the resultset
SELECT table1.*, table2.b_time
FROM table1
...
END$$
DELIMITER ;
And call your procedure once from php
...
$sql = 'CALL sp_myproc(?, ?)';
$query = $db->prepare($sql);
$query->execute(array($stop_id1, $stop_id2));
$result = $query->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
Now regarding the first part of your question why do I get wrong results? OUTER joins can be tricky and especially when you chain them. You can easily filter some rows out or produce additional rows (which happens most often).
Those few joins that you removed may be the cause.
Anyway provided information is not enough for conclusive answer.
But I would suggest instead of returning columns as table1.* specify all columns explicitly and give explicit aliases for columns that have the same names in different tables that are part of a join.
I am building a site and i need to retrieve some information. I have this query.
$SQL = "SELECT distretto_108, provinca_113, regioni_116, tipologia_pdv_106,
richiesta_ccnl_107, coop_va_109, nome_pdv_110,
indirizzo_pdv_111, localita_112
FROM civicrm_value_informazioni_su_tute_le_schede_p_22 ";
I need to add this other code:
WHERE civicrm_event.title_en_US='".addslashes($_GET["titles"])."'
but it's not working...
i need to compare let's say the id of another table with the id of the current table... How to do that?
Thanks in advance...
You should learn something about joining tables...
Do not know what the relation is between the two tables (simply said: what column from one table is pointing to what column at other one), but try something similar (modification needed to meet You DB structure) - now lets assume both tables have related column called event_id:
$SQL = "SELECT distretto_108, provinca_113, regioni_116, tipologia_pdv_106,
richiesta_ccnl_107, coop_va_109, nome_pdv_110,
indirizzo_pdv_111, localita_112
FROM civicrm_value_informazioni_su_tute_le_schede_p_22 cvistlsp22
LEFT JOIN civicrm_event ce ON ce.event_id = cvistlsp22.event_id
WHERE ce.title_en_US='".mysql_real_escape_string($_GET["titles"])."'";
civicrm_value_informazioni_su_tute_le_schede_p_22 table name is very long and You will not be able to create a table with such long name in other DBMS (e.g. ORACLE), so try to make it shorter while still self-describing...
If You want to join tables they have to have a relation, read more about relations and how to use them here: http://net.tutsplus.com/tutorials/databases/sql-for-beginners-part-3-database-relationships/
You are retrieving the data from table civicrm_value_informazioni_su_tute_le_schede_p_22 in your query while the where clause you are adding, refers to the table civicrm_event. You need to add this new table in the from clause and do a join among the two tables using some common key. Example below:
$SQL = "
SELECT distretto_108, provinca_113, regioni_116, tipologia_pdv_106, richiesta_ccnl_107, coop_va_109, nome_pdv_110, indirizzo_pdv_111, localita_112
FROM civicrm_value_informazioni_su_tute_le_schede_p_22
JOIN civicrm_event ON civicrm_value_informazioni_su_tute_le_schede_p_22.ID_PK = civicrm_event.ID_FK
WHERE civicrm_event.title_en_US='".addslashes($_GET["titles"])
";
You need to replace the ID_PK and ID_FK with the relevant Primary and Foreign Keys that bind the tables together.
Please note using query params like that is not recommended. Please read PHP Documentation here for more explanation.
I have a table for users. But when a user makes any changes to their profile, I store them in a temp table until I approve them. The data then is copied over to the live table and deleted from the temp table.
What I want to achieve is that when viewing the data in the admin panel, or in the page where the user can double check before submitting, I want to write a single query that will allow me to fetch the data from both tables where the id in both equals $userid. Then I want to display them a table form, where old value appears in the left column and the new value appears in the right column.
I've found some sql solutions, but I'm not sure how to use them in php to echo the results as the columns in both have the same name.
Adding AS to a column name will allow you to alias it to a different name.
SELECT table1.name AS name1, table2.name AS name2, ...
FROM table1
INNER JOIN table2
ON ...
If you use the AS SQL keyword, you can rename a column just for that query's result.
SELECT
`member.uid`,
`member.column` AS `oldvalue`,
`edit.column` AS `newvalue`
FROM member, edit
WHERE
`member.uid` = $userId AND
`edit.uid` = $userId;
Something along those lines should work for you. Although SQL is not my strong point, so I'm pretty sure that this query would not work as is, even on a table with the correct fields and values.
Here is your required query.
Let suppose you have for example name field in two tables. Table one login and table 2 information. Now
SELECT login.name as LoginName , information.name InofName
FROM login left join information on information.user_id = login.id
Now you can use LoginName and InofName anywhere you need.
Use MySQL JOIN. And you can get all data from 2 tables in one mysql query.
SELECT * FROM `table1`
JOIN `table2` ON `table1`.`userid` = `table2`.`userid`
WHERE `table1`.`userid` = 1
I am joining two tables: customers and queries.
I am getting the full_name from the customers table and the description from the queries table.
I am wondering if it is possible to have the results of an SQL join split into arrays that correspond with the table the data came from? For example:
$STH = $DBH->prepare("SELECT queries.description, customers.full_name FROM queries INNER JOIN customers ON queries.customer_id = customers.id");
$STH->execute();
$queries = $STH->fetchAll();
At the moment, I can access my data like this: $queries[0]['description'] and $queries[0]['full_name']
However, my question is whether there is an easy way to get the data like so: $job[0]['query']['description'] and $job[0]['customer']['full_name'].
Just as teresko mentioned, I can't understand why you'd need that.
I can only imagine you want to see on the PHP code what are the table that contained the information.
Maybe you could do something like SELECT queries.description as queries_description, then your php code would look like $queries['queries_description']. Would it be enough?
You can loop through the results in PHP and convert it to the data structure you want, but you cannot (as far as I know) automatically group the data into arrays based on the source table. A (somewhat messy) alternative, using SQL is to use a multi-query and create a temp table from your original results, then select the results on a per-table basis, like so:
CREATE TEMPORARY TABLE q AS
(SELECT queries.description, customers.full_name FROM queries
INNER JOIN customers
ON queries.customer_id = customers.id
);
SELECT q.description FROM q;
SELECT q.full_name FROM q;
So, in those SELECT statements, you'll have to list all the columns that you want for each result. Then in PHP, you'll have to iterate over each resultset and put the data into arrays (or objects/whatever) as needed. Errr. A fetchAll will still not get you what you want, but a fetchAll on the first non-empty resultset will get you all the rows from queries and the 2nd will get you all the rows from customers
I had my query set up the other day as so
$query = "SELECT card_id,title,description,meta_description,seo_keywords,price
FROM cards,card_cheapest order by card_id";
As you can see, I was selecting card_id,title,description,meta_description,seo_keywords from the table cards, and price was coming from cheapest_card. They both have the card_id in common (in both tables). However, I ran into a bit of an issue. When I run the query in navicat lite, I receive an error "card_id is ambiguous". Was I doing something wrong?
When 2 or more tables have a column that is named the same, you have to qualify the table you want the column to be from.
i.e.:
$query = "SELECT cards.card_id,title,description,meta_description,seo_keywords,price
FROM cards,card_cheapest order by card_id";
Furthermore, do you really want to run the query this way, without a WHERE/JOIN-clause to define how to JOIN the two tables?
$query = "SELECT cards.card_id,title,description,meta_description,seo_keywords,price
FROM cards,card_cheapest WHERE cards.card_id = card_cheapest.card_id
ORDER BY card_id";
When you have the same column name in two tables you're selecting from, you have to prefix the part in the SELECT with one of the table names (it doesn't matter which if it's the same data)
such as SELECT cards.card_id, ...
EDIT: However, cularis's answer is much more explanatory than mine, and take note about joining the two card_id columns if you want to get correct results.
When you run queries that get information from multiple tables with shared field names you need to specify from which table you want to extract what field. You do this by specifying the table name before the field name.
In your case you have two options:
cards.card_id or card_cheapest.card_id.
Also I agree with #cularis, you are probably better of doing a join, but still you will need to specify which card_id you want to select: the one from cards or card_cheapest.