Get the ancestral data from database dynamically - php

I would like to get the ancestral or child data when I pass the value in a function.
This is my data from MySQL table.
If I pass the value of Document2 in my function i want to get the ancestral data, for example, if I pass Document2 it will get the Book2 then the Book2 will get the Document1 and Document1 will get the Book1 and so on, then same with the Profile1 it will get the Document0 dynamically.
Here's my code.
$binded = array('Document2');
$sources = [];
foreach ($binded as $document) {
$check = $this->db->where('binded',$document)
->get('binded_document');
$results = $check->result();
foreach($results as $key => $result){
array_push($sources, $result->source);
$ancestral = $this->db->where('binded',$result->source)
->get('binded_document');
$ancestrals = $ancestral->result();
foreach($ancestrals as $k => $r){
array_push($sources, $r->source);
}
}
}
The problem with my code is it will not dynamically get ancestral data if the passed value in the function has more than 2 ancestral.

DBFIDDLE
I did choose to separate the recursive parts with a -.
WITH RECURSIVE cte AS (
SELECT
source as s,
CAST(Binded AS CHAR(1024)) as b,
1 as c
FROM table1 WHERE Binded='Document2'
UNION ALL
SELECT table1.source, CONCAT(cte.s,'-',cte.b), c+1
FROM cte
LEFT JOIN table1 ON table1.Binded = cte.s
WHERE c<10 AND NOT cte.s IS NULL
)
select b
from cte
where cte.s is null and NOT b is null
group by b
;
output:
b
Document0-Profile1-Document2
Book1-Document1-Book2-Document2

Related

Issue sorting inside while loop

I have a strange issue happening. I've got a table where I want to order the number of times a product was sold. I'll post the query, but the issue is inside the while loop.
Query:
$cat = $db->query("SELECT *, COUNT(id_produto) as quantos FROM produtos p JOIN pedidos m ON p.id_prod = m.id_produto GROUP BY id_produto ORDER BY quantos +0 DESC");
$cat->execute();
Now the loop:
while($res_cat = $cat->fetch(PDO::FETCH_ASSOC)){
$quantidade_ok = $res_cat['quantos'] * $res_cat['qtde'];
$quanti = array($quantidade_ok);
rsort($quanti);
foreach($quanti as $ord){
echo $ord."<br>";
}
The output is:
40
50
4
1
3
2
10
But I want it to be:
50
40
10
4
3
2
1
I'll be happy for any help.
You're sorting within a loop (so your sorting already happened), and you're sorting an array with just 1 value $quanti, so your sort does nothing.
You have 2 ways to approach this properly: edit your query to actually sort how you wish, or sort the PHP array before looping it.
Option 1: Edit your query
Based on your code it seems clear that you wish to sort by the product of quantos times qtde. So you can simply edit your query as follows:
SELECT *, COUNT(id_produto) as quantos
FROM produtos p JOIN pedidos m ON p.id_prod = m.id_produto
GROUP BY id_produto
ORDER BY (quantos*qtde) DESC
Option 2: Sort via PHP
If you prefer to sort via PHP as you don't want to change your query, you can simply populate a temporary array, the product of quantos times qtde as key and then use krsort to sort the array.
In code:
$array = [];
while ($res_cat = $cat->fetch(PDO::FETCH_ASSOC)) {
$key = $res_cat['quantos'] * $res_cat['qtde'];
$array[$key] = $res_cat;
}
krsort($array);
foreach ($array as $ord => $res_cat) {
echo $ord."<br>";
}
You overwrite $quanti each time so it always has a single value.
Try this:
$quanti = [];
while($res_cat = $cat->fetch(PDO::FETCH_ASSOC)) {
$quantidade_ok = $res_cat['quantos'] * $res_cat['qtde'];
$quanti[] = $quantidade_ok;
}
rsort($quanti);
foreach($quanti as $ord){
echo $ord."<br>";
}

Finding a value in a php array

I've been banging my head hard over this problem for the last 2-3 days trying to see the problem from as many different angles as possible but to no avail. I'm turning to the SO community for extra perspectives. Below is the code I have which prints all 9 product plans. I'm wanting to find and print the plan with pricing equals or closest to a given user input. How can I do this?
//arrays of productnames
$productnames=array(1=>"Beginner","Advanced","Expert");
//arrays of productlevels
$productlevels=array(1=>"Bronze","Silver","Gold");
//Get The Length of Product Name Array
$planname_array_length=count($productnames);
//Get The Length of Product Level Array
$planlevel_array_length=count($productlevels);
for ($prn=1; $prn <= $planname_array_length; $prn++) {//loop to create plan name indicators
for ($prl=1; $prl <= $planlevel_array_length; $prl++) {//loop to create plan level indicators
$getpoductsql = " SELECT name, level,productNameId,productLevelId,finalProductPrice
FROM (
SELECT wspn.productName AS name, wspl.productLevel AS level, wsp.productNameId AS productNameId, wsp.productPlanLevel AS productLevelId,
ROUND(SUM(`Price`) * 1.12) AS finalProductPrice,
FROM `products` ws
left join product_plan wsp on wsp.productId = ws.wsid
left join product_plan_level wspl on wsp.productPlanLevel = wspl.wsplid
left join product_plan_name wspn on wspn.wspnid = wsp.productNameId
WHERE wspn.productName = '$planname_array_length[$pn]' AND wspl.productLevel = '$planlevel_array_length[$pl]'
)
AS x ORDER BY ABS(finalProductPrice - $compareprice)"
$resultproducts = $conn->query($getpoductsql);
$prodArray = mysqli_fetch_array($resultproducts);
//print array of each plan
$resultArr = array('planNameID' => $prodArray['planNameId'],
'planName' => $prodArray['name'],
'planLevelID' => $prodArray['planLevelId'],
'planLevelName' => $prodArray['level'],
'planPrice' => $prodArray['finalProductPrice'];
//print arrays of products
echo json_encode($resultArr);
}
}
This will output 9 plans as follow :
{"planNameID":"1","productName":"Beginner","productLevelID":"1","productLevelName":"Bronze","productPrice":"15"}
Rather than performing a separate query for each product name and product level, do them all in one query, and let MySQL find the one with the closest price.
$getpoductsql = " SELECT name, level,productNameId,productLevelId,finalProductPrice
FROM (
SELECT wspn.productName AS name, wspl.productLevel AS level, wsp.productNameId AS productNameId, wsp.productPlanLevel AS productLevelId,
ROUND(SUM(`Price`) * 1.12) AS finalProductPrice,
FROM `products` ws
left join product_plan wsp on wsp.productId = ws.wsid
left join product_plan_level wspl on wsp.productPlanLevel = wspl.wsplid
left join product_plan_name wspn on wspn.wspnid = wsp.productNameId
WHERE wspn.productName IN ('Beginner', 'Advanced', 'Expert') AND wspl.productLevel IN ('Bronze', 'Silver', 'Gold')
GROUP BY productNameId, productLevelId
)
AS x ORDER BY ABS(finalProductPrice - $compareprice)"
forgive my formatting, I'm on mobile
Like Amr Berag said above, your result should be the first row returned from your query.
If you have a table like this:
ID value
---- ------
A 7
B 12
C 23
...
You can then SELECT from this table to find the closest to some value, like so:
(Assume your desired value is $VALUE)
SELECT id, value, ABS(value - $VALUE) AS diff
FROM your_table
ORDER BY diff ASC
This will return something like this (say $VALUE is 10):
id value diff
-- ------ ----
B 12 2
A 7 3
C 23 13
...
You can just pick the first row.
You may also be able to add a WHERE clause to only select the row with the least difference using the MIN function:
SELECT id, value, ABS(value - $VALUE) AS diff
FROM your_table
WHERE diff = MIN(diff)
The way you are doing it will produce invalid json, do it like this:
$result=array();
for ($prn=1; $prn <= $planname_array_length; $prn++) {
for ($prl=1; $prl <= $planlevel_array_length; $prl++) {
. . . // the other code
//print array of each plan
$resultArr = array('planNameID' => $prodArray['planNameId'],
'planName' => $prodArray['name'], 'planLevelID' => $prodArray['planLevelId'],
'planLevelName' => $prodArray['level'],
'planPrice' => $prodArray['finalProductPrice'];
//print arrays of products
$resul[]=$resultArr;
}//loop1
}//loop2
echo json_encode($result);
you should also add the limit 1 and do the rest in JS in the front end

get the value of the key in an array in php without foreach loop and for loop

I have an array and I need to change the value of a column but without looping, because it duplicates the results
$job_query = $this->db->query('SELECT * from job j , company c where j.company = c.id')->result_array();
$companyC = $this->db->query('SELECT j.company ,c.title, c.city, c.logo , c.logo , c.contact FROM job j , company c where c.id = j.company')->result_array();
I need the column company in the first query changes to be that
$job_query['company']=$companyC[key];
but I a get the key without loop of array_map
In codeigniter result_array() returns the all records in the form of array.So you have to use foreach loop for accessing columns.But if you want to only the first record then use row_array() as below:
$job_query = $this->db->query('SELECT * from job j , company c where j.company = c.id')->row_array();
$companyC = $this->db->query('SELECT j.company ,c.title, c.city, c.logo , c.logo , c.contact FROM job j , company c where c.id = j.company')->row_array();
Then
$job_query['company'] = $companyC[key];
yes i did that and it works the problem is that i had 2 queries but now i fixed it and don't need the first i took the value from the second one any way thanks it helped.
foreach ($job_query as $key => $value) {
assigned a anew value here
$new = array();
}
You can use array_column function for that
array_column($array, $columnname);
$array is the array you have
$columnname is the name of the key

How can sort records by low value. All record in same row in my table

How can i sort the records with same values:
This is the example of values currently i have in my table
record_id a_id b_id c_id a_value b_value c_value
25 A B C 450 390 395
Sorry im not able to create table here.
I'm using Php/MySQL Backend.
I need the following output:
B 390
C 395
A 450
It should be sort by lower value with the id name as well.
I know if all these records in different different rows. it was easy to sort by small value. buy using MIN function of mysql.
Im not sure how to sort this in same row records.
You can accomplish this with php, for example:
<?php
$row = ...
$myArray = array(
'A' => $row['a_value'],
'B' => $row['b_value'],
'C' => $row['c_value'],
);
asort($myArray);
echo '<pre>';
print_r($myArray);
echo '</pre>';
If you like to make it dynamic then you can do something like this:
<?php
$row = ...
$myArray = array();
foreach ($row as $column => $value) {
if (strpos($column, '_value') !== FALSE) {
$myArray[strtoupper(substr($column, 1))] = $value;
}
}
asort($myArray);
echo '<pre>';
print_r($myArray);
echo '</pre>';
SELECT record_id, mim(
SELECT a_value FROM table t2 WHERE t1.record_id = t1.record_id UNION ALL
SELECT b_value FROM table t3 WHERE t3.record_id = t1.record_id UNION ALL
SELECT c_value FROM table t4 WHERE t4.record_id = t1.record_id )
FROM table t1
Your sql should fallow the logic above. I canĀ“t test as i dont have mysql in this pc.

SQL: can I JOIN 2 tables according the first table "array" value?

Im trying to find a better way to return 2 tables at once.
My first table is:
[ID] [area]
1 13,12,15
6 18,17,13
and the second table is:
[areaname] [singlearea]
textOf12 12
textOf18 18
textOf15 15
Now, I need to return for each [ID] hits area names, for example:
For the ID: 1, I need the following array: (textOf12,textOf15)
and for the ID 6 I need: (textOf18) only.
This is what i have for now (I don't think its a nice code):
$getall = "SELECT * FROM table1";
$resultfull = mysql_query($getall);
while ($res = mysql_fetch_assoc($resultfull))
{
$uarray = array();
$sqlarea = explode(",", $res['area']);
foreach($sqlarea as $userarea)
{
$areaarray = runquery("SELECT areaname From table2 WHERE singlearea = '".$userarea."'");
$value = mysql_fetch_object($areaarray);
array_push($uarray,$value->areaname);
}
var_dump($uarray);
any suggestions?
Thank you very much!
Comma separated ID list and ID value pretty good matching using like:
select t1.id, t2.areaname
from table1 t1, table2 t2
where concat(',', t1.area, ',') like concat('%,', t2.singlearea, ',%')
However It's recommended to use additional link table!

Categories