Codeigniter JOIN - not a unique table/alias issue - php

I have bookings tables from several countries (for example: book_uk) these tables contain information about our customers in different countries such as name, address, etc etc. Then in my results table I have the results of all tests this customer has had, the information is 'linked' by a PIN number, eg 336699, this number is referenced in both the book_uk table and the results table.
What I want to do is select all data from the book_uk table and then link each row to the results table (where the PIN matches) but I keep getting not a unique table/alias, here is my model code:
$database->select($new_country_columns)
->from($country_table);
$database->select($p_results_cols)
->from($table);
$database->join('p_results', $join, 'inner');
$database is defined earlier on in the model
Produces this error:
Error Number: 1066
Not unique table/alias: 'p_results'
SELECT `book_uk`.`pin`, `book_uk`.`clinic`, `book_uk`.`dob`, `book_uk`.`gender`, `book_uk`.`country`, `book_uk`.`order_date`, `p_results`.`pin`, `p_results`.`code`, `p_results`.`name`, `p_results`.`result` FROM (`book_uk`, `p_results`) INNER JOIN `p_results` ON 'book_uk.pin = p_results.pin'
Filename: C:/xampp/htdocs/projects/b2k-stat/system/database/DB_driver.php
Line Number: 691
what I really need to do is select data from book_uk and then run a foreach loop on the results table and add any data with matching PIN to the results array, I have no idea how to do this, I tried to loop through it with a foreach loop but it kept coming up blank, i've also tried:
$database->select($new_country_columns)
->from($country_table)
->join('p_results', $join, 'inner');
But this also gives me zero results, any help? Thanks in advance

Remove
'p_results'
from your
FROM
clause since your joining it right after that.

Not sure if this is the best way to do things, but I solved my issue by generating 2 queries and running an IF statement inside a foreach loop on both queries like so:
$database->select($new_country_columns)
->from($country_table);
$query1 = $database->get()->result_array();
$p_results->select($p_results_cols)
->from($table);
$query2 = $p_results->get()->result_array();
foreach($query1 as $row){
foreach($query2 as $rows) {
if($row['pin'] === $rows['pin']) {
$new_row = array_merge($row, $rows);
$query[] = $new_row;
}
}
}
return $query;
This code gave me an array of the combined data that was needed to display in my view

Related

I need to nest 2 arrays so that I can echo order header as well as order item details

I have updated my original post based on what I learned from your comments below. It is a much simpler process than I originally thought.
require '../database.php';
$pdo = Database::connect();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM Orders WHERE id = 430";
$q = $pdo->prepare($sql);
$q->execute(array($id));
$data = $q->fetch(PDO::FETCH_ASSOC);
echo 'Order Num: ' . $data['id'] . '<br>';
$sql = "SELECT * FROM Order_items
JOIN Parts ON Parts.id = Order_Items.part_id
WHERE Order_Items.orders_id = 430";
$q = $pdo->prepare($sql);
$q->execute(array($line_item_id));
$data = $q->fetch(PDO::FETCH_ASSOC);
while ($data = $q->fetch(PDO::FETCH_ASSOC))
{
echo '- ' . $data['part_num'] . $data['qty'] . "<br>";
}
Database::disconnect();
Unfortunately, only my first query is producing results. The second query is producing the following ERROR LOG: "Base table or view not found: 1146 Table 'Order_items' doesn't exist" but I am expecting the following results.
Expected Results from Query 1:
Order Num: 430
Expected Results from Query 2:
- Screws 400
- Plates 35
- Clips 37
- Poles 7
- Zip ties 45
Now that I understand where you are coming from, let's explain a couple of things.
1.PDO and mysqli are two ways of accessing the database; they essentially do the same things, but the notation is different.
2.Arrays are variables with multiple "compartments". Most typical array has the compartments identified by a numerical index, like:
$array[0] = 'OR12345'; //order number
$array[1] = '2017-03-15'; //order date
$array[2] = 23; //id of a person/customer placing the order
etc. But this would require us to remember which number index means what. So in PHP there are associative arrays, which allow using text strings as indexes, and are used for fetching SQL query results.
3.The statement
$data = $q->fetch(PDO::FETCH_ASSOC)
or
$row = $result->fetch_assoc()
do exactly the same thing: put a record (row) from a query into an array, using field names as indexes. This way it's easy to use the data, because you can use field names (with a little bit around them) for displaying or manipulating the field values.
4.The
while ($row = $result->fetch_assoc())
does two things. It checks if there is a row still to fetch from the query results. and while there is one - it puts it into the array $row for you to use, and repeats (all the stuff between { and }).
So you fetch the row, display the results in whatever form you want, and then loop to fetch another row. If there are no more rows to fetch - the loop ends.
5.You should avoid using commas in the FROM clause in a query. This notation can be used only if the fields joining the tables are obvious (named the same), but it is bad practice anyway. The joins between tables should be specified explicitly. In the first query you want the header only, and there is no additional table needed in your example, so you should have just
SELECT *
FROM Orders
WHERE Orders.Order_ID = 12345
whereas in the second query I understand you have a table Parts, which contains descriptions of various parts that can be ordered? If so, then the second query should have:
SELECT *
FROM Order_items
JOIN Parts ON Parts.ID = Order_Items.Part_ID
WHEERE Order_Items.Order_ID = 12345
If in your Orders table you had a field for the ID of the supplier Supplier_ID, pointing to a Suppliers table, and an ID of the person placing the order Customer_ID, pointing to a Customers table, then the first query would look like this:
SELECT *
FROM Orders
JOIN Suppliers ON Suppliers.ID = Orders.Supplier_ID
JOIN Customers ON Customers.ID = Orders.Customer_ID
WHERE Orders.Order_ID = 12345
Hope this is enough for you to learn further on your own :).

MySQL return rows where column contains categories defined by array (and add weight to the results)

In my app, the user can type in an indefinite amount of categories to search by. Once the user hits submit, I am using AJAX to call my PHP script to query my DB and return the results that match what the user defined for the categories.
My category column is separated as so for each row: "blue,red,yellow,green" etc.
I have two questions:
How can I pass an array to MySQL (like so: [blue,yellow,green]) and then search for each term in the categories column? If at-least one category is found, it should return that row.
Can MySQL add weight to a row that has more of the categories that the user typed in, therefor putting it further to the top of the returned results? If MySQL cannot do this, what would be the best way to do this with PHP?
Thanks for taking the time and looking at my issue.
For the part 1 you can use the function below:
<?php
function createquery($dataarray){
$query="select * from table where ";
$loop=1;
foreach($dataarray as $data)
{
$query.="col='$data'";
if(count($dataarray)<$loop-1){
$query.=' or ';
}
$loop++;
}
return $query;
}
?>
This will return the long query.
use this some like this:
mysql_query("select * from table where category in (".implode($yourarray,',').")");
1)
Arrays are not passed to a MySQL database. What's past is a query which is a string that tells the database what action you want to preform. An example would be: SELECT * FROM myTable WHERE id = 1.
Since you are trying to use the values inside your array to search in the database, you could preform a foreach loop to create a valid SQL command with all those columns in PHP, and then send that command / query to the database. For example:
$array = array('blue', 'red', 'yellow', 'green');
$sql = "SELECT ";
foreach ($array as $value)
{
$sql .= $value.", ";
}
$sql .= " FROM myTable WHERE id = 1";
IMPORTANT! It is highly recommended to used prepared statements and binding your parameters in order not to get hacked with sql injection!
2)
You are able to order the results you obtained in whichever way you like. An example of ordering your results would be as follows:
SELECT * FROM myTable WHERE SALARY > 2000 ORDER BY column1, column2 DESC

Codeigniter active record left join issue

I have two tables 'accounts_transactions' and 'accounts_bills_transactions'.
I have to left join these two using active record of codeigniter.But the names of key columns used to join are different.So I am not getting the key column from the left table in the output .What query should I write to get the key column from the left table included in the result.
My code is
$this->db->select('*');
$this->db->from('accounts_transactions');
$this->db->join('accounts_bills_transactions', 'accounts_transactions.id = accounts_bills_transactions.transaction_id','left');
$query = $this->db->get();
So, as you see the key columns used to join here are , id from left table and transaction_id from second table.The problem is that I am not getting the id from left table in the result.But I am getting all other columns.I assume the problem is because of difference in column names used to join.ie both the column names are not named 'id' .So how can I get the id from left table included in the result.
You could alias them:
$this->db->select('accounts_transatctions.*, account_transactions.id AS a_id,
accounts_bills_transactions.*,
account_bills_transactions.id AS ab_id');
$this->db->from('accounts_transactions');
$this->db->join('accounts_bills_transactions', 'accounts_transactions.id = accounts_transactions.transaction_id','left');
$query = $this->db->get();
The two IDs will now be available as a_id and ab_id (or whatever alias you choose)
Note: I'm not sure if you can alias in AR without avoiding escaping (haven't been using CI for a while). Should you get any error for that reason, just pass false as second parameter of $this->db->select():
$this->db->select('...', false);
you can try this if you confuse of using $this->where or $this->join
$query = $this->db->query("select ......");
return $query;
You problem is so simple. You can use this query
$query = $this->db
->select('at.*')
->select('abt.id as abt_id');
->from('accounts_transactions at');
->join('accounts_bills_transactions abt', 'at.id = abt.transaction_id','left');
->get()
->result();
When same column are used in join it selects only one. You need to give alise to the other column in second table. The best practice is to use a structure like this
accounts_transatctions
--------------------------
accounts_transatctions_id
other_columns
accounts_bills_transactions
---------------------------
accounts_bills_transactions_id
accounts_transatctions_id
other_columns

I want to get output result from second table based on first table rows output in json-php

I have knowledge of PHP but I am still learning Json. First of all I want to clear what I am looking for. I have two tables in mysql database, table1(users) and table2(business). Table "users" contains these rows(id, uid, business_name) and table "business" contains these rows(id, uid, category).
I have following code in PHP page:
if(isset($_GET['catName'])) {
$cat = $_GET['catName'];
$stmt = $pdo->prepare("SELECT id, uid, category FROM business WHERE category = ? ");
$stmt->execute(array($_GET['catName']));
$arr = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
I am able to get json output on my html page e.g.
101, 102, 103 and so on.
But I want to get business_name rows like ABC Business, XYZ Business, 123 Business and so on from second table "business" based on the output uid from first table. In brief, I want business_name output instead of uid output from second table.
Please help me. Thank you so much in advance.
You have an associative array, with the results from the query. It sounds like you want the business names, but you are not querying for them.
So the first step would be fix your broken query!
It's difficult to tell what you want from the query, but you're mixing the users table with the business table, so I'm guessing you really want business names based on users.
SELECT b.business_name FROM users u JOIN business b ON u.uid = b.uid WHERE category = ?
Then, you have to access your $arr variable correctly to get the business names
foreach ($arr as $bus_sql_result) {
echo $bus_sql_result['business_name']."\n";
}
This is not in JSON format, I'm not sure what JSON has to do with what you want, but if you really want it that way, you could try something like
$business_names = array();
foreach ($arr as $bus_sql_result) {
$business_names[] = $bus_sql_result['business_name'];
}
echo json_encode($business_names);
Thank you so much Chris and Jormundir. Joining the both tables really solved my problem. This is what I have done:
$stmt = $pdo->prepare("SELECT business.uid, users.business_name FROM business,users WHERE business.uid = users.uid AND business.category= ? ");
In html page I have put "business_name" array instead of "uid" and I have got result whatever I was looking for.
Thanks you so much all of you.

Order MySQL results by number of related rows in foreign table

Alright, so I have a table outputting data from a MySQL table in a while loop. Well one of the columns it outputs isn't stored statically in the table, instead it's the sum of how many times it appears in a different MySQL table.
Sorry I'm not sure this is easy to understand. Here's my code:
$query="SELECT * FROM list WHERE added='$addedby' ORDER BY time DESC";
$result=mysql_query($query);
while($row=mysql_fetch_array($result, MYSQL_ASSOC)){
$loghwid = $row['hwid'];
$sql="SELECT * FROM logs WHERE hwid='$loghwid' AND time < now() + interval 1 hour";
$query = mysql_query($sql) OR DIE(mysql_error());
$boots = mysql_num_rows($query);
//Display the table
}
The above is the code displaying the table.
As you can see it's grabbing data from two different MySQL tables. However I want to be able to ORDER BY $boots DESC. But as its a counting of a completely different table, I have no idea of how to go about doing that.
There is a JOIN operation that is intended to... well... join two different table together.
SELECT list.hwid, COUNT(log.hwid) AS boots
FROM list WHERE added='$addedby'
LEFT JOIN log ON list.hwid=log.hwid
GROUP BY list.hwid
ORDER BY boots
I'm not sure if ORDER BY boots in the last line will work like this in MySQL. If it doesn't, just put all but the last line in a subquery.
But the result of the query into an array indexed by $boots.
AKA:
while(..){
$boot = mysql_num_rows($query);
$results[$boot][] = $result_array;
}
ksort($results);
foreach($results as $array)
{
foreach($array as ....)
{
// display table
}
}
You can switch between ksort and krsort to switch the orders, but basically you are making an array that is keyed by the number in $boot, sorting that array by that number, and then traversing each group of records that have a specific $boot value.

Categories