Get data from 2 tables and make a table in one query - php

I have two MySQL tables:
offers:
id | rid | name
------------------------------
1 | 1234 | mary
2 | 1235 | john
3 | 5342 | liam
And
geo_in_off:
offer_id | geo_id
------------------------------
1 | 1234
2 | 1235
3 | 5342
I need to make a table on my website looging like:
1(number) | 1234(rid) | name(name) | 1(geo_id)
But I got MySQL troubles.
My code is:
require('../config.php');
echo "<table class=\"offer-table\">";
echo "<tr><th id=\"off_col_num\">№</th><th id=\"off_col_id\">offer ID</th><th id=\"off_col_name\">Название</th><th id=\"off_col_geo\">Geo</th></tr>";
$i = 1;
$sql ="SELECT * FROM `offers` ORDER BY `rid` JOIN geo_in_off ON geo_in_off.id = offers.id";
$result = mysql_query($sql) or die(mysql_error());
while ($row=mysql_fetch_assoc($result)) {
echo "<tr><td>" . $i . "</td><td>" . $row['rid'] . "</td><td>" .
$row['name'] . "</td><td>" .$i . "</td></tr>" ;
$i++;
}
echo "</table>";
I've got problems with MySQL synaxis and the logic how to get the data from 2 tables and give the result in one "while loop".
So I need to join 2 queries in one:
$sql ="SELECT * FROM `offers` ORDER BY `rid`";
$sql ="SELECT `geo_id` FROM `geo_in_off` WHERE `offer_id` = '$each_offer_id_from_offers'";
And optional but not necessary:
$sql ="SELECT `name` FROM `geo` WHERE `id` = '$geo_id_got_from_table_geo_in_off'";
And get a table where I get the offer id, the offer name and the offer geo.

Try this query, it does help you (full join query)
SELECT offers.*, geo_in_off.geo_id FROM offers,
geo_in_off WHERE offers.id=geo_in_off.offer_id

Change
$sql ="SELECT * FROM `offers` ORDER BY `rid` JOIN geo_in_off ON geo_in_off.id = offers.id";
To
$sql ="SELECT * FROM `offers` JOIN `geo_in_off` ON `geo_in_off`.`offer_id` = `offers`.`id` ORDER BY `offers`.`rid`";
1) ORDER BY order is wrong in your query
SELECT column1, column2, ...
FROM table_name
ORDER BY column1, column2, ... ASC|DESC;
2) Instead of geo_in_off.id = offers.id use geo_in_off.offer_id = offers.id

Try this query:
$sql = 'SELECT of.id, of.rid, of.name, geo.id
FROM of.offers
INNER JOIN of.id = geo.offer_id
WHERE offer_id = \''.$each_offer_id_from_offers.'\' order by of.rid'

Related

MySQLi Repeat Row Depending on Column Quantity Value

I have created a simple SQL statement to display which products customers have purchased from a woo commerce store.
This is working great but i'm struggling to find a SQL function that repeats rows based on a value, maybe one doesn't exist and PHP is required, any help would be great.
Thanks
CURRENT VIEW
ORDER ID. | PRODUCT NAME. | QTY
-------------------------------------
123 | APPLE | 3
124 | ORANGE | 2
125 | PEAR | 1
DESIRED VIEW
ORDER ID. | PRODUCT NAME. | QTY
-------------------------------------
123 | APPLE | 3
123 | APPLE | 3
123 | APPLE | 3
124 | ORANGE | 2
124 | ORANGE | 2
125 | PEAR | 1
CODE
<?php
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT wppc_wc_customer_lookup.customer_id, wppc_wc_customer_lookup.first_name,
wppc_wc_customer_lookup.last_name, wppc_wc_customer_lookup.email,
wppc_wc_order_stats.customer_id, wppc_wc_order_stats.total_sales,
wppc_wc_order_stats.order_id, wppc_wc_order_stats.date_created, wppc_wc_order_stats.status,
wppc_woocommerce_order_items.order_id, wppc_woocommerce_order_items.order_item_name,
wppc_woocommerce_order_items.order_item_id, wppc_woocommerce_order_itemmeta.order_item_id,
wppc_woocommerce_order_itemmeta.meta_id, wppc_woocommerce_order_itemmeta.meta_key,
wppc_woocommerce_order_itemmeta.meta_value FROM wppc_wc_customer_lookup
LEFT JOIN wppc_wc_order_stats ON wppc_wc_customer_lookup.customer_id =
wppc_wc_order_stats.customer_id
LEFT JOIN wppc_woocommerce_order_items ON wppc_wc_order_stats.order_id =
wppc_woocommerce_order_items.order_id
LEFT JOIN wppc_woocommerce_order_itemmeta ON wppc_woocommerce_order_items.order_item_id =
wppc_woocommerce_order_itemmeta.order_item_id
WHERE wppc_woocommerce_order_itemmeta.meta_key = '_qty' AND
wppc_woocommerce_order_items.order_item_name = 'Product Name' AND
wppc_wc_order_stats.status = 'wc-completed'
ORDER BY wppc_wc_order_stats.date_created DESC";
$result = $conn->query($sql);
echo "<table border=\"1\"><tr>";
echo "<tr><th>Order ID</hr><th>First Name</hr><th>Last Name</hr><th>Email</hr><th>Total</hr>
<th>Order Date</hr><th>Product Name</hr><th>Quantity</hr>";
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<tr><td>".$row["order_id"]. " </td><td> " .$row["first_name"] . " </td><td> " .
$row["last_name"] . " </td> <td> " . $row["email"] . " </td><td> &pound".$row["total_sales"]
. " </td> <td>".$row["date_created"] . " </td> <td> ".$row["order_item_name"] . " </td> <td>
".$row["meta_value"] . " </td></tr> ";
}
} else {
echo "0 results";
}
echo "</table>";
$conn->close();
?>
This is working great but i'm struggling to find a SQL function that repeats rows based on a value, maybe one doesn't exist and PHP is required, any help would be great.
the idea is to make multiple select queries with different where clauses;
for instance in this case we need query like this:
SELECT * FROM table WHERE QTY > 0
UNION ALL
(SELECT * FROM table WHERE QTY > 1)
UNION ALL
(SELECT * FROM table WHERE QTY > 2)
ORDER BY `ORDER ID`
so we can create mysql procedure to generate such query depending on maximum qty like so
CREATE PROCEDURE GetAllProducts()
BEGIN
select max(QTY) - 1 into #maxQty from table;
set #resQry = 'SELECT * FROM table WHERE QTY > 0';
set #i = 0;
label1:
LOOP
IF #i = #maxQty THEN
leave label1;
END IF;
SET #i = #i + 1;
SET #resQry = CONCAT(#resQry, ' UNION ALL (SELECT * FROM table WHERE QTY > ', #i, ')');
END LOOP label1;
SET #resQry = CONCAT(#resQry, ' ORDER BY `ORDER ID`');
PREPARE stmt FROM #resQry;
EXECUTE stmt;
END;
and then you can call this procedure
CALL GetAllProducts();
If you are running MySQL 8.0, you can do this with a recursive query. Starting from your existing query, that would be:
with recursive
data as ( <... your query goes here ...> ),
rcte as (
select order_id, product_name, qty, 1 rn from data
union all
select order_id, product_name, qty, rn + 1 from rcte where rn < qty
)
select order_id, product_name, qty from rcte
In earlier versions, you could use a table of numbers. Here is an example that would quantities up to 3:
select d.*
from ( <... your query goes here ...> ) d
inner join (select 1 qty union all select 2 union all select 3) n
on n.qty <= d.qty
You can expand the subquery with more union alls to handle greater quantities.

Dynamically selecting tables in mySQL

I have a query in mySQL
SELECT id FROM admin_products;
which return a list of ids, like so
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+------+
And I was using PHP to dynamically generate tables like
vendor_1, vendor_2, vendor_3, vendor_4, vendor_5
Now I want to write a query to retrieve the price and quantity from the table id
For example
"ENTER QUERY HERE"
Should retrieve
+-----------------------------+
| id | price | quantity |
+-----------------------------+
| 1 | 23| 13| // price and quantity retrieved from table vendor_1 since id=1
| 2 | 158| 85| // price and quantity retrieved from table vendor_2 since id=2
| 3 | 15| 7| // price and quantity retrieved from table vendor_3 since id=3
| 4 | 112| 9| // price and quantity retrieved from table vendor_4 since id=4
| 5 | 123| 199| // price and quantity retrieved from table vendor_5 since id=5
+-----------------------------+
What I'm doing now in PHP is:
$conn = mysqli_connect($server,$user,$pwd,$db);
$sql = "SELECT id FROM admin_products";
$res = mysqli_query($conn,$sql);
if(mysqli_num_rows($res)>0){
while($row = mysqli_fetch_assoc($res)){
$product = array();
$innerSQL = "SELECT price,quantity FROM vendor_".$row['id'];
$innerRes = mysqli_query($conn,$innerSQL);
if(mysqli_num_rows($innerRes)>0){
while($innerRow = mysqli_fetch_assoc($innerRes)){
array_push($product,$row['id']);
array_push($product,$innerRow['price']);
array_push($product,$innerRow['quantity']);
}
}
}
}
But it takes two hits to the mySQL database. Can't it be reduced to one?
EDIT
I have later on realized that my database structure was incorrect and dynamically creating tables is a very bad idea and could spell disaster later on
-Solution 1:
Note: This will only work if you have in your vendor_x tables id for the vendor id to match them with. (As Strawberry said, this is a terrible idea to dynamically generate tables).
After selecting the correct id you can do something like this:
connect to the MySql Server
Then you can create the table name and store it in a variable.
$tableName = 'vendor_' . $id;
I would suggest after that to have a check if the table exists with a simple query:
$sql = "SHOW TABLES LIKE '$tableName'";
If this returns empty result you can throw an exception that the table does not exist or handle it whatsoever way you would like.
After checking every table, to be sure it exists, you can create your query.
$joins = "";
$sql = "
SELECT
v.id,
price,
quantity
FROM
vendors AS v
";
foreach ($ids as $id) {
$tableName = "vendor_" . $id;
$tableAlias = "v".$id;
$joins .= " LEFT JOIN " . $tableName . " AS ". $tableAlias ."
ON (v.id = ". $tableAlias .".vendor_id) ";
}
$sql .= $joins;
Then execute the query.
-Solution 2:
Create only one table to manage your vendors. It should have a structure like this :
`id` // AI value
`vendor_id` // The id of the vendor to easily join it afterwards
`price`
`quantity`
You can name it something like vendor_product or whatsoever
And now you have only one simple query:
$sql = "
SELECT
v.id,
vp.quantity,
vp.price
FROM
vendors AS v
LEFT JOIN vendor_product AS vp
ON (vp.vendor_id = v.id)
";
EDIT for the comment about the structure:
You will need one table for the vendors, such so:
`vendor`:
`id`, //AI value
`username`,
`password` // I suggest to you not to keep it in plain text.
`vendor_product` :
`id`, //AI value
`vendor_id`,
`price`,
`quantity`
I don't know here if you are going to store more information about each product, but this should do the trick.
How to show the product with least price ?
You need to match them by somehow and group by that selecting minimum price.
Try this if it suits
$table = "vendor"."_".$id; // this will create table name if $id = 1 then $table = vendor_1;
mysqli_query($connect , "SELECT * FROM $table");
2nd
If you want to fetch data of all table at once then
1) fetch id from admin_products and store in an array like
$ids = array(1,2,3,4,5);
2) Now loop throw array and create sql;
$sql = "SELECT * FROM ";
$ids = array(1,2,3,4,5);
foreach($ids as $id){
$table = "vendor"."_".$id; // this will create table name if $id = 1 then $table = vendor_1;
$sql .=" $table,";
}
$sql = rtrim($sql,",");// this will trim the last comma
echo $sql;
// output SELECT * FROM vendor_1, vendor_2, vendor_3, vendor_4, vendor_5

How to select record from two different tables

I have two tables which is
+----------------------------+
| task |
+----------------------------+
| id | t_title | t_assign_to |
+----------------------------+
+-----------------------------+
| task_employee |
+-----------------------------+
| id | emp_name | emp_underon |
+-----------------------------+
My question is that i want to fetch t_assign_to FROM task table which having emp_underon = '2' in task_employee table with foreign key (t_assign_to)
<?php
$sql = mysql_query("SELECT * FROM task");/// i got all value from here
$sql=mysql_query("SELECT * FROM task_employee WHERE emp_underon ='2'");// i got all value from here
//$sql=mysql_query("SELECT * FROM task UNION SELECT * FROM task_employee WHERE emp_underon='2'");
$count = mysql_num_rows($sql);
while($row=mysql_fetch_assoc($sql))
{
echo $row['t_assign_to'];
}
?>
I think the t_assign_to is the foreign key for task_employee
So i JOIN them together
Schema 1
$sql = "SELECT * FROM task t INNER JOIN task_employee te ON t.t_assign_to = te.id";
Schema 2
$sql = "SELECT * FROM task t,task_employee te WHERE t.t_assign_to = te.id";
If the field name in table is same with others field in others table, just alter the field name like:
$sql = "SELECT table.field as new_field_name FROM task t,task_employee te WHERE t.t_assign_to = te.id";
For you convenient,
$sql = "SELECT * FROM task t INNER JOIN task_employee te ON t.t_assign_to = te.id WHERE te.emp_underon = '2' "
$q = mysql_query($sql);
$c = mysql_num_rows($q);
if($c > 0)
{
while($r = mysql_fetch_assoc($q))
{
echo $r['t_assign_to'];
}
}
I hope you can get your answer by this query though I did not test this SQL.
select task.t_title, task.t_assign_to, task_employee.id as emp_id, task_employee.emp_name from task inner join task_employee on task.t_assign_to = task_employee.emp_underon where task_employee.emp_underon = 2

Get column value (name) from a Foreign Key reference in PHP

I've got two databases fruit and fruit-prices (for arguement's sake).
In fruit there are two columns id | name
Fruit table
id | name
1 | Apple
2 | Banana
In fruit_prices there are three columns id | fruit_id | price where fruit_id is a FOREIGN KEY reference.
id | fruit_id | price
1 | 1 | £2.00
2 | 2 | £3.00
Now I have a PHP function that will print out a table row and cells with the information from the database but currently if I am printing two fruits out my table looks like this.
Name | Price
1 | £2.00
2 | £3.00
PHP Code:
$query = mysqli_query($conn, "SELECT * FROM fruits ");
while($row = mysqli_fetch_assoc($query)) {
$name = $row['fruit_id']; //for comma separation
$price = $row['price'];
echo "<tr>";
echo "<td>" .$name. "</td>" .
"<td>" .$price. "</td>";
echo "</tr>";
}
Is there an elegant way I can retrieve the name of the fruit (i.e. 1 = Apple, 2 = Banana). Rather than using the unique ID of each fruit.
So then my table will look like this
Name | Price
Apple | £2.00
...
I hope this makes sense? I'm new to RD concepts. This is a very simple example and does not reflect my entire project so I'm just wondering if this is achievable?
This can be done by joining both the tables.Change your sql query with below one.I think it will solve your problem.
"SELECT fruit.name,fruit_prices.price FROM fruit,fruit_prices WHERE fruit_prices.fruit_id = fruit.id";
You would want to use a join and specify the columns you would like to select.
SELECT f.name, fp.price FROM fruit as f
JOIN fruit-prices as fp ON f.id=fp.fruit_id;
It is achievable using JOIN:
SELECT * FROM fruits a JOIN fruits-prices b ON b.fruit_id = a.id
For more friendly column names you can add column aliases and use them further.
You say they are in two databases, but I think it might just be two tables. If so:
select * from fruit f
left outer join fruit-prices fp
on f.id = fp.fruit_id
The left outer join ensures that if a fruit doesn't have a price it will be returned will null as the price. If you don't want that replace it with an inner join.
Use of JOIN does what you need.
"SELECT `p`.`price`, `f`.`name` FROM `fruit_prices` `p`
JOIN `fruits` `f` ON `f`.`id` = `p`.`fruit_id`"
Be wary - use of SELECT * here will lead to an error, as both tables have an id field, and the query will break.
You need a join between the tables,
SELECT f.name, fp.price
FROM fruit f
INNER JOIN fruit_price fp ON f.id = fp.fruit_id
Well, you need to take a look to SQL Joins
query = mysqli_query($conn, "SELECT FRUIT.name,FRUIT_PRICES.price FROM fruits INNER JOIN FRUIT_PRICES ON FRUIT.id = FRUIT_PRICES.fruit.id");
while($row = mysqli_fetch_assoc($query)) {
$name = $row['name']; //for comma separation
$price = $row['price'];
echo "<tr>";
echo "<td>" .$name. "</td>" .
"<td>" .$price. "</td>";
echo "</tr>";
}
What I wrote means : "Select FRUIT.Name,FRUIT_PRICES.price in FRUIT AND FRUIT_PRICES, considering that FRUITS.id is related to FRUIT_PRICES.id_fruit"
Suggestion : You can have a single table viz fruits with 3 columns id, fruit_name, price.
for your table structure :
SELECT fruits.id, name, price
FROM fruits, fruit-prices
WHERE fruit_id=fruits.id;

Query to list which string how many occured in a table?

I have an array of strings and a table with text type column. I want to list which string how many occured in specified column of any row in table. Is there a way to do this with one query?
Example;
$strings = array('test', 'sth');
Table;
id | someTextColumn
-------------------
1 | abc tests
2 | sthab
3 | teststh
4 | abcd
5 | sth
Expected result;
str | occurences
-----------------
test | 2
sth | 3
You can do this with a series of like statements.
Here is an example:
select totest.str, count(t.id)
from (select 'test' as str union all
select 'sth'
) totest left outer join
t
on t.someTextColumn like concat('%', totest.str, '%')
group by totest.str
This is not going to be particularly fast if your tables are large. If you have largish tables, you might want to consider full-text indexing.
If the table size isn't too large and the column is properly indexed:
SELECT 'test', COUNT(id)
FROM tableName
WHERE someTextColumn LIKE '%test%'
UNION ALL
SELECT 'sth', COUNT(id)
FROM tableName
WHERE someTextColumn LIKE '%sth%'
$query = "select someTextColumn, count(id) from tableName where "
for($i=0; $i < count($Strings); $i++)
{
if($i != 0)
$query .= " OR ";
$query .= "someTextColumn =" . $string[$i];
}
$query .= " group by someTextColumn";
$result = mysql_query($query);
Try this I hope this will solve ur problem!!

Categories