MySQL Query: Concatenate horizontally based on selected ids - mysql

Say I have a table 'table_name' with two columns like this:
table_name
------------
my_id | data
------|-----
id1 | 312
id1 | 523
id1 | 128
id2 | 239
id2 | 479
id2 | 121
id3 | 639
id3 | 429
id3 | 131
id4 | 473
id4 | 872
id4 | 662
id4 | 174
id4 | 272
I tried around a while and I now found a way to select the ids I want to use:
SELECT DISTINCT my_id from table_name WHERE (my_id REGEXP 'id[234]')
This gives me the ids 'id2', 'id3' and 'id4'. How would I formulate a query that gives me my desired output, based on the selected ids as below?
id2 | id3 | id4
---------------
239 | 639 | 473
479 | 429 | 872
121 | 131 | 662
NaN | NaN | 174
NaN | NaN | 272

If your table really only has those two columns and there is no related data that can be used to order the data column like you have shown, then there is no good way to achieve the ordering you're looking for.
Relational data doesn't have any intrinsic "order" to it, even if you've inserted that data in a particular order or displayed it in a certain way here. If your table really only has those two columns, it will be difficult to match the "first" id2 value with the "first" id3 value and so on to get to your desired output. We could potentially rank them in a query and match them based upon that rank (ascending or descending) or even provide some random order capability, but there is no documented (i.e. reliable) way to get the order that you've provided.
While a table does have a physical order to the underlying bits in storage, and some products allow you to access them via a physical rowid (Oracle), no RDBMS that I know of (including MySql) guarantees the order in which the rows will be returned unless an order by clause is used in your select statement. This is literally by design and is considered a "feature" that came out of E.F. Codd's research.

First make a function that select distinct of the id's
public function get_id_of_table_name() {
$sql = 'SELECT DISTINCT my_id ';
$sql .= 'FROM table_name ';
$query = $this->db->query($sql);
$result = $query->row();
foreach ($result as $key => $value)
{
$result->data = $this->get_data($result->my_id);
}
return ( $query->num_rows() ) ? $result : FALSE;
}
And create the second function that will gather all the data's base on what id's
public function get_data($my_id) {
$params = [];
$sql = 'SELECT data ';
$sql .= 'FROM table_name ';
$sql .= 'WHERE my_id = ? ';
$params[] = $my_id;
$query = $this->db->query($sql, $params);
$result_data = $query->result();
$data = [];
foreach ($result_data as $result)
{
array_push($data, $result->data);
}
return $data;
}
You can put a where clause in the first function if you want.
$sql .= 'WHERE my_id = ? ';
and add the params
$params[] = $my_id;
You can also add parameters my_id as array in the first function so that you can get what id you want to get
$id = ["id2","id3","id4"];
public function get_id_of_table_name($id) {
$params = [];
$sql = 'SELECT DISTINCT my_id ';
$sql .= 'FROM table_name ';
$sql .= 'WHERE 1 ';
foreach ($id as $my_id)
{
$sql .= 'OR (my_id = ?) ';
$params[] = $my_id;
}
$query = $this->db->query($sql, $params);
$result = $query->row();
foreach ($result as $key => $value)
{
$result->data = $this->get_data($result->my_id);
}
return ( $query->num_rows() ) ? $result : FALSE;
}

Related

How to get data of joined table using query() method

I have an issue with getting data of the joined table if I use query().
I did not get the data of product table, how can I solve this using query() without using Active record?
Here is my db table structure
category table
+--------------------------+
| cId | added | category |
+-----+--------+-----------+
| 1 | 1.2.20 | PC |
| 2 | 1.7.20 | electron |
+-----+--------+-----------+
product table
+--------------------------+
| id | cId | cost |
+-----+--------+-----------+
| 1 | 1 | 3000 |
| 1 | 2 | 9000 |
+-----+--------+-----------+
My Model
protected $table = 'category';
public function showProduct()
{
$sql = "SELECT
category.*, COALESCE(SUM(product.cost),0) as price
FROM category
JOIN product
ON product.cId = category.cId
GROUP BY category.cId
";
$this->db->query($sql);
return $this;
}
My Controller
public function index()
{
$result = $this->model->showProduct();
echo "<pre>";
print_r($result->asObject()->paginate(1));
//pagination
$pager = $this->model->showProduct()->pager->links();
}
Result I get
Array
(
[0] => stdClass Object
(
[cId] => 1
[added] => 1.2.20
[category] => PC
)
[1] => stdClass Object
(
[cId] => 2
[added] => 1.7.20
[category] => electron
),
)
You are requested to run this code.
SELECT category.cId,category.added,category.category,product.id,COALESCE(SUM(product.cost),0) as price
FROM category,product
WHERE category.cId=product.cId
GROUP BY category.cId;
If you are using CodeIgniter-4 then you can easily write this using Query Builder Class.
$sql="SELECT category*,product* FROM category INNER JOIN product.cid=category.id WHERE category.id";
I found solution to this by setting this table property within a function.
Model
$protected $table = array("default bd table here");
public function showProduct()
{
$this->table = array('category');
$sql = "SELECT
category.*, COALESCE(SUM(product.cost),0) as price
FROM category
JOIN product
ON product.cId = category.cId
GROUP BY category.cId
";
$this->db->query($sql);
return $this;
}
My Controller
public function index()
{
$result = $this->model->showProduct();
//pagination
$pager = $this->model->showProduct()->pager->links();
}

Mysql Nested and declare as array

I have 2 table that want to call in and make another array from it.
The first table is groups
| id | name | type |
1 premium pr
2 basic bs
The second table is sub-groups
| id | group_id | name |
1 1 forever
2 2 short
Actually I want to show the code like this. To have another array function declare as sub-groups
Array (
[id] => 1
[name] => Premium
[type] => pr
)[sub-groups] => Array (
[0] => Array (
[id] => 1
[group_id] => 1
[name] => forever))
I created this PDO sql connection
=================EDITED CODE====================
function getGroups(){
global $conn;
$stmt = $conn->prepare("SELECT * FROM groups");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$groups = $stmt->fetchAll();
foreach($groups as $key => $val){
$stmt = $conn->prepare("SELECT * FROM sub_groups WHERE group_id = {$val['id']}");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$program = $stmt->fetchAll();
foreach($program as $key => $val){
$groups['sub-groups'] = $program;
}
}
return $groups;
}
The code successfully show the groups Premium and Basic, But it's not showing the sub-groups inside the main groups. Did I miss something?
Anyone with help will be nice.
Array keys have to be unique. If you have two columns with the same name, only one of them can appear in the resulting associative array for the rows.
You need to assign an alias to at least one of the columns with the same name so it will show up differently in the results.
SELECT g.name as group_name, sg.group_id, sg.id AS subgroup_id, sg.name AS subgroup_name
FROM groups AS g
LEFT JOIN subgroups AS sg ON sg.group_id = g.id
When you're creating the PHP result, $groups['sub-groups'] needs to be an array. You're overwriting it with a single element each time through the loop.
<?php
function getGroups(){
global $conn;
$groups = [];
$stmt = $conn->prepare("
SELECT g.name as group_name, sg.group_id, sg.id AS subgroup_id, sg.name AS subgroup_name
FROM groups AS g
LEFT JOIN subgroups AS sg ON sg.group_id = g.id");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($row = $stmt->fetch()){
if (!isset($groups[$row['group_name']])) {
$groups[$row['group_name']] = $row;
$groups[$row['group_name']]['sub-groups'] = [$row['subgroup_name']];
} else {
$groups[$row['group_name']]['sub-groups'][] = $row['subgroup_name'];
}
}
return $groups;
}

I want to separate values in mysql using join in codeigniter

My mysql table look like
ranks are rank1,rank2,rank3 on id 1
but i want to show like that
id 1 -> rank1
id 1 -> rank2
id 1 -> rank 3
My sql Query
$this->db->select('rank')->from('rank_restriction');
$data = $this->db->get();
$query = $data->result_array();
foreach ($query as $result) {
if (!empty($result['rank'])) {
$result['rank'] = explode('||', $result['rank']);
}
return $query
}

Compare two element in same table and return difference/missing data

How to compare two IDs from same table and get difference/missing data ?
I have form for current product($current_id) where i display data from X product($id).
Data look like : name1 name2 name3
Than you can select to insert some of this data for current product($current_id) (for example: name1 name2 )
Than you have 2 records in oc_product_option_value
(oc_option_value_description hold names , oc_product_option_value hold ids and more)
$id data = name1 name2 name3
$current_id data = name1 name2
Later one if you come back to current product($current_id) and you pull same X product data($id) have to display only data = name3
How to compare that to get this result ?
public function getInfo($id, $current_id){
$query = $this->db->query("SELECT
oc_product_option_value.*,
oc_option_value_description.name
oc_product_option_value
LEFT JOIN oc_option_value_description ON (oc_product_option_value.option_value_id = oc_option_value_description.option_value_id)
WHERE product_id = '" . $id . "'");
}
I done this with additionally query and small php code , did not found way to do whole thing with one query and without php
$masterProduct = $this->model_catalog_product->getMatrakOptionsMasterProduct($id);
$currentProduct = $this->model_catalog_product->getMatrakOptionsCurrentProduct($current_id);
$data['options'] = array();
$current = array_column($currentProduct, 'name');
foreach($masterProduct as $value){
if(!in_array($value['name'], $current)){
$data['options'][] = $value;
}
}
and both querys
public function getMatrakOptionsMasterProduct($id){
$query = $this->db->query("SELECT
oc_product_option_value.*,
oc_option_value_description.name
FROM oc_product_option_value
LEFT JOIN oc_option_value_description ON (oc_product_option_value.option_value_id = oc_option_value_description.option_value_id)
WHERE product_id = '" . $id . "'");
}
public function getMatrakOptionsCurrentProduct($current_id){
$query = $this->db->query("SELECT
oc_product_option_value.*,
oc_option_value_description.name
FROM oc_product_option_value
LEFT JOIN oc_option_value_description ON (oc_product_option_value.option_value_id = oc_option_value_description.option_value_id)
WHERE product_id = '" . $current_id . "'");
}

I a, getting error - Warning: mysql_fetch_assoc() expects parameter 1 to be resource

Here is the code.........
<?php
include('../inc/php/inc/dbc.php');
$query = "SELECT * FROM available_fsv WHERE a_status = '1'";
$result_query = mysql_query($query);
while($row = mysql_fetch_assoc($result_query)){
$billingid = $row['billingid'];
$query = "UPDATE available_fsv SET b_status = '1' WHERE billingid = '$billingid'";
$result_query = mysql_query($query);
echo $result_query;
}
?>
The error i am getting...........
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in C:\wamp\www\php\fsv_shutdown_cron.php on line 6
Database structure is like--
____________________________________________________
| id | a_status | b_status | billingid |
|--------|------------|-------------|--------------|
| 1 | 1 | 0 | 1 |
|--------|------------|-------------|--------------|
| 2 | 0 | 0 | 12 |
|--------|------------|-------------|--------------|
| 3 | 0 | 0 | 9 |
|--------|------------|-------------|--------------|
| 4 | 1 | 0 | 3 |
|________|____________|_____________|______________|
What i wanna do is if a_status is 1 then update b_status to 1.
I am learning php and I know this is a stupid question but please help me. Thanks in advance.. :)
you mess up the $query and $result_query, they appeared twice in the code
error is on the while($row = mysql_fetch_assoc($result_query)){ line.. here your $result_query is nothing but the response of your update query..
try this :
<?php
include('../inc/php/inc/dbc.php');
$query = "SELECT * FROM available_fsv WHERE a_status = '1'";
$result_query = mysql_query($query);
while($row = mysql_fetch_assoc($result_query)){
$billingid = $row['billingid'];
$update_query = "UPDATE available_fsv SET b_status = '1' WHERE billingid = '$billingid'";
$update_result_query = mysql_query($update_query);
echo $update_result_query;
echo "<br />";
}
?>
This call mysql_query($query) returned FALSE, instead of result set, which means that your query had errors in it. Use the following code to see the error:
$result_query = mysql_query ($query);
if ($result_query === FALSE)
{
echo (mysql_error ());
die (1);
}
Looks like I was wrong. You really overwrite original value of $result_query when you execute your update query.
you can directly update using inline IF
UPDATE tableName
SET b_status = IF(a_status = 1, 1 , b_status )
if you are executing this, you don't need to communicate on the database twice.