I would like some help on this, i have a table like this
CREATE TABLE IF NOT EXISTS `items` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`code` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`unitPrice` decimal(8,2) NOT NULL,
`quantity` int(11) NOT NULL,
`totalSold` int(11) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
and after using DB::table('items')->get();
i would like to get the same result as if i run this sql command
"select `code`,(`unitPrice`*(`quantity`+`totalSold`)) as totalEarnIfsold from `items` order by `totalEarnIfsold` desc"
what i have been able to achieve without success ofc is this:
$items_all->sortBy([
$totalEarnIfsold= fn ($a) => $a->unitPrice *($a->quantity+$a->totalSold),
['totalEarnIfsold', 'desc'],
]);
So i need your help if you may ofc, and thanks
You can do in following way
First you need to calculate totalEarnIfsold with map function and after that you can easily sort with value.
$items_all = $items_all->map(function($item) {
$item->totalEarnIfsold = $item->unitPrice *($item->quantity + $item->totalSold);
return $item;
})->sortByDesc('totalEarnIfsold');
Related
I have 4 tables : peoples, companies, countries and the pivot table company_people (as peoples & companies both belongs to many) which has both people_id and company_id.
In the People model, I have the following functions:
class People extends Model
{
// main company (only one)
public function company()
{
return $this->belongsTo(Company::class);
}
// all other companies
public function companies()
{
return $this->belongsToMany(Company::class);
}
public function country()
{
return $this->belongsTo(Country::class);
}
}
Then in the People controller, I have the following in order to prepare to display a list of all the peoples with the related main company name (only one), country name (only one) and other companies as a list of names. I can do the first 2 but not the last one. How can I do that?
$peoples = People::orderBy($sortField,$sortOrder)
->with(['companies','company','country'])
->get();
foreach ($peoples as $people) {
$people->company = '['.$people->company->company.']'; // main company name
$people->country = '['.$people->country->country.']'; // country name
$people->otherCompanies = ? // list of other company names through pivot table
}
And here all the structure of the 4 tables:
CREATE TABLE `company_people` (
`id` bigint NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`company_id` bigint UNSIGNED NOT NULL,
`people_id` bigint UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `countries` (
`id` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'AA',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`is_active` int NOT NULL DEFAULT '1',
`country` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `peoples` (
`id` bigint UNSIGNED NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`is_active` int NOT NULL DEFAULT '1',
`firstname` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`lastname` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '',
`country_id` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'ZA',
`company_id` bigint UNSIGNED DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci PACK_KEYS=0;
ALTER TABLE `company_people`
ADD PRIMARY KEY (`id`),
ADD KEY `article_id` (`company_id`),
ADD KEY `tag_id` (`people_id`);
ALTER TABLE `countries`
ADD PRIMARY KEY (`id`);
ALTER TABLE `peoples`
ADD PRIMARY KEY (`id`),
ADD KEY `country_id` (`country_id`),
ADD KEY `company_id` (`company_id`);
ALTER TABLE `company_people`
MODIFY `id` bigint NOT NULL AUTO_INCREMENT;
ALTER TABLE `peoples`
MODIFY `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `peoples`
ADD CONSTRAINT `peoples-company` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `peoples-country` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE `companies`
ADD CONSTRAINT `peoples-country` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE `company_people`
ADD CONSTRAINT `companies-peoples` FOREIGN KEY (`company_id`) REFERENCES `companies` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `peoples-companies` FOREIGN KEY (`people_id`) REFERENCES `peoples` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
you can use pluck() to get all the company name then toArray() to convert in array like this
$peoples = People::orderBy($sortField,$sortOrder)
->with(['companies','company','country'])
->get();
foreach ($peoples as $people) {
$people->company = '['.$people->company->company.']'; // main company name
$people->country = '['.$people->country->country.']'; // country name
$people->otherCompanies = $people->companies->pluck('name')->toArray(); // list of other company names through pivot table
}
And if you want otherCompanies name as comma seprate then use $people->companies->pluck('name')->join(',');
I am trying to write a query in my controller to display Quiz result for students. I have these tables
CREATE TABLE IF NOT EXISTS `quizz_question` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`topic` varchar(1000) COLLATE utf8_unicode_ci NOT NULL,
`question_code` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`answer1` varchar(100) COLLATE utf8_unicode_ci NULL,
`answer2` varchar(100) COLLATE utf8_unicode_ci NULL,
`answer3` varchar(100) COLLATE utf8_unicode_ci NULL,
`answer4` varchar(100) COLLATE utf8_unicode_ci NULL,
`topic` varchar(1000) COLLATE utf8_unicode_ci NOT NULL,
`correct_answer` varchar(100) COLLATE utf8_unicode_ci NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;
CREATE TABLE IF NOT EXISTS `quizz_attempt` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`student_code` varchar(1000) COLLATE utf8_unicode_ci NOT NULL,
`answer` varchar(100) COLLATE utf8_unicode_ci NULL,
`question_code` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;
The two tables became these two model classes: QuizzQuestion and QuizAttempt.
In quizz_attempt, if a student select an answer (answer), it will take answer and question_code in quizz_attempt and compare with quizz_question.
quizz_attempt.answer = 1 then it will choose the content in answer1 as correct answer
quizz_attempt.answer = 2 then it will choose the content in answer2 as correct answer
quizz_attempt.answer = 3 then it will choose the content in answer3 as correct answer
quizz_attempt.answer = 4 then it will choose the content in answer4 as correct answer
public function gameQualifiers(Request $request)
{
$revenuedetails = DB::table('quizz_attempt as g')
->select(
'g.student_code',
'g.answer'
)
->orderByRaw('g.created_at DESC');
}
I know I need to join the two tables for the result. I started the code in my controller, but don't know how to complete it. i want to write a query to display list of students who choose correct answers
The quiz attempt should have the quizz_question_id as a Foreign Key. This will make it easier down the line to have the two connected.
You can set up two models to match your database tables: QuizzQuestion and QuizzAttempt. You can set up Foreign Keys like so:
QuizzAttempt.php
public function quizzQuestion()
{
return $this->belongsTo('App\QuizzQuestion');
}
And QuizzQuestion.php
public function quizzAttempts()
{
return $this->hasMany('App\QuizzQuestion');
}
So now, you want to get all of the attempts where the answer is correct - you are looking at an instance of QuizzQuestion, e.g.
$question = QuizzQuestion::find(1); // first question
$correctResults = QuizzAttempts::where('quizz_question_id', $question->id)
->where('answer', $question->correct_answer)
->pluck('student_code');`
Now you have all the student codes of the students that got the correct answers.
*** Update
If you cannot change the structure of the tables, you can run the following query:
// 1) find the question you want the answers for
$question = QuizzQuestion::find(1);
// 2) retrieve the correct results
$correctResults = QuizzAttempts::where('question_code', $question->question_code)
->where('answer', $question->correct_answer)
->pluck('student_code');`
In documents specified that with SPH_SORT_TIME_SEGMENTS i can sort my timestamp DESCENDED, but how i can sort my timestamp ASCENDED? i trying using SPH_SORT_ATTR_ASC but the it shows null results. i tried it using "modified_date" (using sql_attr_timestamp) and "integered_modified_date" (using sql_attr_bigint) and both of it still showing no results
here's my configuration
source member_private_messages {
type = mysql
sql_host = 192.168.7.101
sql_user = root
sql_pass =
sql_db = proto_db
sql_query = SELECT \
b.message_id as primary_message_id, \
b.message_id as message_id, \
CONCAT(a.first_name, ' ',a.last_name) AS `from` , \
CONCAT(c.first_name, ' ',c.last_name) AS `to` , \
message_from_id, \
deliver_object_id, \
message_title, \
message_content, \
UNIX_TIMESTAMP(modified_date) AS modified_date, \
UNIX_TIMESTAMP(modified_date) AS integered_modified_date \
FROM tbl_member a JOIN \
tbl_messages b JOIN \
tbl_member c ON a.register_id = b.message_from_id AND b.deliver_object_id = c.register_id
# FOR SORT BY or FILTER
sql_attr_bigint = message_id
sql_attr_bigint = message_from_id
sql_attr_bigint = deliver_object_id
sql_attr_string = message_title
sql_attr_string = message_content
sql_attr_timestamp = modified_date
sql_attr_bigint = integered_modified_date
}
here is my php
<?php
require_once "sphinxapi.php";
$client = new SphinxClient();
$client->SetServer('localhost', 9312);
$client->SetConnectTimeout(30);
$client->SetArrayResult(true);
// Sort the index
$client->SetMatchMode(SPH_SORT_ATTR_ASC ,'modified_date'); //RETURNS NULL
// Query the index
$results = $client->Query('','member_private_messages_index');
// Output the matched results in raw format
var_dump($results['matches']);
here is my database structure (it haves 2 simple data)
CREATE TABLE `tbl_member` (
`member_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`register_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`register_type` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`first_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`registration_date` datetime DEFAULT NULL,
`verification_date` datetime DEFAULT NULL,
`update_date` datetime DEFAULT NULL,
PRIMARY KEY (`member_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;
CREATE TABLE `tbl_messages` (
`message_id` int(255) unsigned NOT NULL AUTO_INCREMENT,
`message_from_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`message_from_type` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`is_public` varchar(3) COLLATE utf8_unicode_ci DEFAULT NULL,
`message_type` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`deliver_object_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`deliver_object_type` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`message_title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`message_content` blob,
`created_date` datetime DEFAULT NULL,
`modified_date` datetime DEFAULT NULL,
PRIMARY KEY (`message_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;
$client->SetMatchMode(SPH_SORT_ATTR_ASC ,'modified_date'); //RETURNS NULL
Why are you trying to define a sorting mode via setMatchMode? surely should be using setSortMode
btw it shouldnt return anyting. Its just setting a value for use by the later Query.
in get_poll function in following Poll model:
class Poll_model extends CI_Model
{
public function get_poll($parameter) {
$this->db->select('question.id, question.title, question.question, answer.answer')->from('answer')->join('question', 'answer.question_id = question_id')->where('question.id',$parameter);
$query = $this->db->get();
return $query->result_array();
}
Because I'm using join to get result from 2 table and table question and answer both have column content, so in the result_array, the structure like this:
Array ( [id] => 1 [title] => favourate character [content] => Green ) 1
The there's only answer content, I think the question content was overwrite, because both of them have the same column 'content'. the table structure shown below:
CREATE TABLE `answer` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`question_id` int(11) unsigned NOT NULL,
`content` text NOT NULL,
PRIMARY KEY (`id`),
KEY `question_id` (`question_id`),
CONSTRAINT `answer_ibfk_1` FOREIGN KEY (`question_id`) REFERENCES `question` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;
CREATE TABLE `question` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(128) NOT NULL DEFAULT '',
`content` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
Is there any way to solve this problem?
Simply rename the columns inside the ->select() call like this:
$this->db
->select('
question.id id,
question.title title,
question.content question,
answer.content answer')
->from('answer')
->join('question', 'answer.question_id = question_id')
->where('question.id', $parameter);
The result rows now should contain a question and a answer index.
Hello all i have a problem that when i try to join my comment table it show nothing
here is my code
$this->db->select('*,users.profil_billed as profil_billed, forum_traad.id as traad_id');
$this->db->from('forum_traad');
$this->db->join('users', 'forum_traad.brugernavn = users.username');
$this->db->where('forum_traad.fk_forum_kategori', $id);
$this->db->join('forum_kommentare', 'forum_traad.id = forum_kommentare.fk_forum_traad');
$this->db->where('forum_kommentare.fk_forum_traad', 'forum_traad.id');
$this->db->order_by("forum_traad.id", "DESC");
its then i put this in it show nothing, and i dont know why.. do i need some left join, right join etc.? i have try all of it :d
$this->db->join('forum_kommentare', 'forum_traad.id = forum_kommentare.fk_forum_traad');
$this->db->where('forum_kommentare.fk_forum_traad', 'forum_traad.id');
kommentare = comments
traad = thread
brugernavn = username
kategori = categori
its danish,
sorry my bad english hope some one can help me out
my database structure is this and im using mysql
CREATE TABLE `forum_kategori` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`kategori` text NOT NULL,
`beskrivelse` mediumtext NOT NULL,
`godkendt` varchar(4) NOT NULL DEFAULT 'ja',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=10;
CREATE TABLE `forum_kommentare` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fk_forum_traad` int(11) NOT NULL,
`brugernavn` text NOT NULL,
`indhold` mediumtext NOT NULL,
`dato` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`time` text NOT NULL,
`godkendt` varchar(4) NOT NULL DEFAULT 'ja',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=28;
CREATE TABLE `forum_traad` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`overskrift` text NOT NULL,
`indhold` mediumtext NOT NULL,
`fk_forum_kategori` int(11) NOT NULL,
`brugernavn` text NOT NULL,
`dato` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`godkendt` varchar(4) NOT NULL DEFAULT 'ja',
`time` text NOT NULL,
`status` varchar(8) NOT NULL DEFAULT 'aaben',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(80) NOT NULL,
`password` text NOT NULL,
`kon` varchar(5) NOT NULL,
`alder` text NOT NULL,
`hood` varchar(4) DEFAULT NULL,
`fornavn` varchar(60) DEFAULT NULL,
`efternavn` varchar(100) DEFAULT NULL,
`city` text,
`ip` varchar(20) DEFAULT NULL,
`level` text,
`email` text,
`point` int(11) NOT NULL,
`oprettet` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`fritekst` mediumtext NOT NULL,
`profil_billed` text NOT NULL,
`online` varchar(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=31;
and it return nothing and no errors it only show a message i have done with a else statement that said "there is no threads on this categori", i have try with left join, right join inner join full join, ye all of it :S
You should try using a left join on your joins and work from there. If that doesn't work then there isn't a link between the tables.
Try this code:
$this->db->select('*,users.profil_billed as profil_billed, forum_traad.id as traad_id');
$this->db->from('forum_traad');
$this->db->join('users', 'forum_traad.brugernavn = users.username');
$this->db->join('forum_kommentare', 'forum_traad.id = forum_kommentare.fk_forum_traad');
$this->db->where('forum_traad.fk_forum_kategori', $id);
$this->db->order_by("forum_traad.id", "DESC");
You can use after $this->db->get() the
print $this->db->last_query();
and check what's wrong.