I have done up a query builder using join. I would like to show table 2, 3, 4, 5, 6 and so on based on the user id on table 1. I tried to query the result, it is showing like this :
My Tables
Table users
user_id | username | email
1 | userA | userA#email.com
2 | userB | userB#gmail.com
Table add_game
game_id | user_id | ign | acc_id
1 | 1 | ignA | accA
2 | 1 | ignB | accB
1 | 2 | ignB | accB
3 | 2 | ignD | accD
I will be using foreach loop and I believe it will display out multiple times based on the records in the database. What should I do if I only want to display the information highlighted in the red box (which is from users table) just 1 time and all the records associated with user id in add_game table?
This is my current code :
Controller
public function login()
{
$data = [];
helper(['form']);
$validation = \Config\Services::validation();
$db = db_connect();
$model = new LoginModel($db);
$user = $model->login($this->request->getVar('userlogin'));
$this->setUserSession($user[0]);
echo view('templates/header', $data, $user);
echo view('account/login', $data, $user);
echo view('templates/footer', $data, $user);
}
private function setUserSession($user){
$data = [
'user_id' => $user['user_id'],
'username' => $user['username'],
'email' => $user['email'],
'firstname' => $user['firstname'],
'lastname' => $user['lastname'],
'dob' => $user['dob'],
'country' => $user['country'],
'country_code' => $user['c_code'],
'contact' => $user['contact'],
'game_id' => $user['game_id'],
'ign' => $user['ign'],
'acc_id' => $user['acc_id'],
'isLoggedIn' => true
];
session()->set($data);
return true;
}
Model:
return $this->db->table('users')
->groupStart()
->where('username', $str)
->orWhere('email', $str)
->groupEnd()
->join('add_game', 'add_game.user_id = users.user_id')
->get()
->getResultArray();
I have a few more tables but not yet created for now so I have only joined 1 table for the time being. What am I missing? Or do I have to loop twice? Is there a way that I just need to loop 1 time? Hope someone can help me out here. Thanks in advance guys!
the easiest way to achieve this (display 2 records from add_game table and 1 record from users table) you need to create a foreach loop in your view, and exclude duplicated data from users table to be shown.
controller:
$data['my_data']=$this->Your_model->your_method(); // your query example
$this->load->view('your_view',$data)
view:
<?php $my_id=0;foreach($my_data as $row):?>
<?php if($my_id!=$row->user_id):?>
<div><?=$row->username?></div> <!--data from table user-->
<div><?=$row->created_at?></div> <!--data from table add_game-->
<?php else:?>
<div><?=$row->created_at?></div> <!--only data from table add_game-->
<?php endif;?>
<?php $my_id=$row->user_id;endforeach;?>
Related
Im trying to build a SQL Query that will select all orders from a table that matches options that i defined.
Databse i use: Mysql
Language: PHP
Basicly i have a array that looks like this.
[
[
"user_id" => 1,
"product_id" => 5548,
"variation_id" => 14
],
[
"user_id" => 1,
"product_id" => 5548,
"variation_id" => 15
],
[
"user_id" => 1,
"product_id" => 4422,
"variation_id" => 4
]
]
This means that the user(id: 1) has one product with the "id" of 5548, and then he also has 2 variations of that product that are "id" 14 and 15. You can also see that the same user owns the product(id:4422) that has variation(id:4).
I then have a "order_lines" table that looks like this
order_lines
+----+-----+---------+-----------------------------+
| id | uid | user_id | product_id | variation_id |
+----+-----+---------+-----------------------------+
| 1 | 1 | 1 | 5548 | 14 |
+----+-----+---------+-----------------------------+
| 2 | 2 | 1 | 5548 | 15 |
+----+-----+---------+-----------------------------+
| 3 | 3 | 1 | 4422 | 4 |
+----+-----+---------+-----------------------------+
| . | . | . | .... | .. |
+----+-----+---------+-----------------------------+
I now need a SQL Query that selects all the rows where there is a match between the user_id, product_id and variation_id that are defined in the array.
The output should contain all rows that meet these conditions.
I hope someone can pin me in the right direction.
I'm building in Laravel if you got the query builder just at your hand. Else i very much appreciate an SQL Query.
if I am getting you right, below code will help you, using just Core PHP
foreach($array as $arr){
$user_id = $arr['user_id'];
$prodct_id = $arr['prodct_id'];
$variation_id = $arr['variation_id'];
$query = "SELECT * FROM order_lines WHERE user_id = $userId AND product_id = $productId AND variation_id = $variationId";
$queryResult = mysql_fetch_assoc($query);
$yourCollection[] = $queryResult;
}
print_r($yourCollection);
Try below code to use Laravel Query Builder, below code will help you to get results for multiple users based on product and variation.
$qb_order_lines = DB::table('order_lines');
$where_condition = [
['user_id' => '', 'product_id' => '', 'variation_id' => ''],
];
foreach ($where_condition as $condition) {
$qb_order_lines->orWhere(function($query) use ($condition) {
$query->where('user_id', $condition['user_id'])
->where('product_id', $condition['product_id'])
->where('variation_id', $condition['variation_id']);
});
}
$obj_result = $qb_order_lines->get();
If you want to get it for only one user, use below code
$obj_result = DB::table('order_lines')
->where('user_id', $condition['user_id'])
->where('product_id', $condition['product_id'])
->where('variation_id', $condition['variation_id'])
->get();
You can modify the above query builders based on your requirements like select fields or group by.
Let me know if you need any help.
For anyone interesting.
My problem was that i needed to count of many matches that were between my array and my database.
Instead of selecting and outputting. I eneded up using sql count() function in a query, that did the job.
I'm trying to insert records to either two tables or one table depending on if a record exists or not.
First table Authors
ID | Name
1 | Joe
2 | Sam
Second table Books
ID | author_ID | Book
1 | 2 | Book1
2 | 2 | BookYYY
3 | 1 | BookABC
What I want to accomplish is to check if author exists first, if not insert author and his book and if it DOES exists insert just the book with the right author ID
Here is what I've attempted so far that doesn't seem to work.
$result = DB::table('authors')
->where('name', $data['author_name'])
->where('username', $data['author_username'])->pluck('id');
if(is_null($result)){
//Not in table add new author
$id = DB::table('authors')->insertGetId(
['name' => $data['author_name'], 'username' => $data['author_username']]
);
//Add book
DB::table('books')->insert(
['author_id' => '.$id.', 'name' => "Book777"]
);
}
else{
//Is in table insert just book
DB::table('books')->insert(
['author_id' => '.$result.', 'name' => "Book777"]
);
}
So I'm trying to add author with Book name "Book777" but if author does exists in DB get the author ID and insert just the book.
Thank you all for helping me with this! Appreciate any help.
Consider using ORM. With Eloquent you can change all your code to just this:
$author = Author::firstOrCreate(['name' => $data['author_name'], 'username' => $data['author_username']]);
$author->books()->create(['name' => 'Book777']);
With Query Builder you can do this:
$attributes = [
'name' => $data['author_name'],
'username' => $data['author_username']
];
$author = DB::table('authors')->where($attributes)->first();
$authorId = is_null($author) ? DB::table('authors')->insertGetId($attributes) : $author->id;
DB::table('books')->insert(['author_id' => $authorId, 'name' => "Book777"]);
I'm not sure if it's work or not but hope this helps
$result = DB::table('authors')
->where('name', $data['author_name'])
->where('username', $data['author_username'])->pluck('id');
if(!empty($result)){
//Is in table insert just book
DB::table('books')->insert(
['author_id' => $result, 'name' => "Book777"]
);
}
else{
//Not in table add new author
$id = DB::table('authors')->insertGetId(
['name' => $data['author_name'], 'username' => $data['author_username']]
);
//Add book
DB::table('books')->insert(
['author_id' => $id, 'name' => "Book777"]
);
}
i am having product variant table in mysql, i want to prevent duplicate child record for each parent product id:
-----------------------------------------------------
id | product id | category id | variant_value_id' | title
----------------------------------------------------
1 | 11 | 2 | 7
2 | 11 | 3 | 7
this is my mysql table structure.
i want to have unique variant id for each category id.
this is my controller
foreach($this->input->post('product_variant') as $value){
$variant_data = array(
'product_id' => $id,
'category_id' => $this->input->post('product_category'),
'variant_group_id' => $this->Product_model->get_variant_group_by_variant_id($value)[0]->group_id,
'variant_value_id' => $value,
'product_variant_title' => $this->input->post('product_name').' '.$this->Product_model->get_variant_group_by_variant_id($value)[0]->value,
'mrp_price' => '',
'price' =>'',
'slug' => url_title($this->input->post('product_name').'-'.$this->Product_model->get_variant_group_by_variant_id($value)[0]->value, 'dash', true),
'status' =>'',
);
if($this->Product_model->add_product_variant($variant_data)){
$this->session->set_flashdata('product_variant_added', 'Product Variant Created Succesfully');
}
}
Please help. if need more info, i will provide
If you want to prevent duplicate productId, then use the following I mean do a check:
$q = $this->db->select('ProductName')
->from('Table')
->where(array('ProductId' => $ProductId, 'variant_value_id' => $variant_value_id))->get(); //Select query to check the productId
if($q->num_rows() == 0){ //Finally checks if the Id doesn't exist
//Insert goes here
}
else
{
//Already exists
}
I'm collecting input fields as an array to be inserted into the different rows in the database. However it only inserts the first row of the array.
Please kindly assist. I have some issues handling arrays. I don't know how to construct the query and I've tried to search online and I couldn't get enough help. I'll really appreciate help with the query.
Here is my HTML code:
<input type = "text" class = "form_element" name = "wat_office_type[]" />
<input type = "number" name = "wat_office_price[]" class = "form_element" />
while I use jQuery to add more input boxes.
Here is my php:
$wat_office_type_post = $_POST['wat_office_type'];
$wat_office_price_post = $_POST['wat_office_price'];
$wat_office_type = array();
$wat_office_price = array();
foreach ($wat_office_type_post as $type) {
if (!empty($type))
$wat_office_type[] = $afrisoft->antiHacking($type);
}
foreach ($wat_office_price_post as $post) {
if (!empty($post))
$wat_office_price[] = $afrisoft->antiHacking($post);
}
I want to insert into 2 separate rows and achieve something like this:
--------------------------------------------
| Pk | wat_office_type | wat_office_price |
--------------------------------------------
| 1 | executive office | 1000 |
--------------------------------------------
| 2 | Training room | 4000 |
--------------------------------------------
| 3 | Events room | 5000 |
--------------------------------------------
I'll kindly appreciate if I can get help with the insert query (mysql,php) on how I can insert all values of the first array in one column, and values of the second array into the second column, while each are matching d numbers of arrays supplied.
Thanks.
If I understand correctly, you need to combine the two arrays into something like
$list = array(
array('pk' => 1, 'type' => 'executive', 'price' => 1000),
array('pk' => 2, 'type' => 'training room', 'price' => 4000),
array('pk' => 3, 'type' => 'events room', 'price' => 5000)
);
then you can call a foreach loop to query the database with each element, like
foreach($list as $key => $value) {
$sql = "INSERT INTO table_name (pk, type, price) VALUES (?, ?, ?)";
$query = $this->db->prepare($sql);
$params = array($value['pk'], $value['type'], $value['price']);
if($query->execute($params)) {
return true;
} else {
return false;
}
}
so instead doing two foreach loops and putting results in different arrays, you could use one foreach loop and create an associative array for each set of results (I assume the count on both of your arrays is the same?) as I mentioned above.
I have two tables, a main one, and one that supports the main table, very very similar to what wordpress has, posts and posts_meta.
Main table:
id
title,
content
id | title | content
1 | one | content one
2 | two | content two
Meta table:
id
item_id
key
value
id | item_id | key | value
1 | 1 | template | single
2 | 1 | group | top
1 | 2 | template | page
2 | 2 | group | bottom
And my goal is, in the end, have an array with the data from the main table, merged with the meta table. example:
$data = array(
array(
'id' => 1,
'title' => 'one',
'content' => 'content one',
'template' => 'single',
'group' => 'top'
),
array(
'id' => 2,
'title' => 'two',
'content' => 'content two',
'template' => 'page',
'group' => 'bottom'
)
);
What is the best way to achieve this in a way that preforms good?
I am using PDO to connect to my database, and how Im doing right now is, I first query the data on the first table, and then for each result, i query the meta table, I use prepared statements for this, since it's suposed to be fast, but even so, it's harming the performance of my script.
Thank you
Instead of querying meta table for each result from first query
you should extract the ids from the first result:
$rows = q('SELECT * FROM posts');
$byIds = [];
foreach ($rows as &$row)
{
$byIds[$row['id']] =& $row;
}
and run second query:
$rows2 = q('SELECT * FROM posts_meta WHERE item_id IN (' . implode(',', array_keys($byIds)) . ')');
Then loop the results in PHP and merge with first query results.
foreach ($rows2 as $row2)
{
$byIds[$row2['item_id']][$row2['key']] = $row2['value'];
}
You have your merged results in $rows variable now:
var_dump($rows);
This way you will have only 2 db requests.
Please note that i have used $byIds as array of references so i dont have to search row with specific id in second loop. This way order of elements in $rows are preserved.