I have two queries that I need to run to obtain, a list of contracts and a list of sales, due to the fact that there is a duplicate contract for each customer I have written a query that will return customer_id and the date of their final contract while joining on our products table to filter for certain products. another query returns a list of sales for a given area by connecting to a couple of tables as well is their anyway after calling these queries I could join them using php .
$contracts = DB::table('contracts as c').....
$leads= DB::table('contracts as l')..
so after creating these two collections that both have the column customer_id, i want to join them using PHP if these where both tables in my database this would be a simple left_join, however, I can't figure out a way to do it with the output of the quarry .... thanks in advance for all the help. I have been doing some research and think i need to map somehow
$leads = $leads->map(function ($item, $key) {
$single_lead = $contract->where('l.customer_id',$item->spp.customer_id);
return collect($item)->merge($single_lead);
something like this but this is not working and I'm stuck so I should be going through each item in leads and then merge it with the contract information that has the same customer_id
Your question wasn't very clear but giving you a hint to do left join,
You can do it as:
$query = DB::table('contracts')->leftJoin('customer','customer.id','=','contracts.customer_id')->get()
You can see it in the Laravel Docs
Related
I am trying to put together a SQL statement which pulls the names of employees that have a certain title and how many labor hours that they currently have in total for a total of the current week. I am working with two different tables, so I assume that I would need to use JOIN in this case, however my dilemma is that I would need to join two fields from TABLE A to one field on TABLE B. Is this possible?
See below for my code (so far):
public function get_all_techs_with_hours()
{
// get all technicians
$this->db->select('*');
$this->db->from('employees');
$this->db->where('role', 'Body Technician');
$this->db->or_where('role', 'Paint Technician');
$this->db->or_where('role', 'Combo Technician');
$query = $this->db->get();
return $query;
}
In this case, employees is TABLE A and jobs is TABLE B. I need to JOIN TABLE B to TABLE A based on jobs.body_tech matching employees.first_name and employees.last_name. Atleast, I think I do. I'm sure I'm going about this the hardest approach possible, but I can't seem to find any helpful manual to learn how to do this. In the end, all I would like to do is combine all hours for each technician and add to the same array using two different tables.
I have been trying to figure out how to check if any of one column's items present in another column in Codeigniter....
I have Bike,Car,Bus in a column(Vehicles) in a table1...
I also have Bus,Helicopter,Ship,Car in a column(Interested) in table2..
How to check if any of table2 interested column's items present in table1 vehicles column...
I tried like this...
$query = $this->db->get('table2');
foreach($query->result() as $row)
{
$a = explode(',', $row->interested);
$this->db->where_in('Vehicles', $a);
$query = $this->db->get('table1');
foreach($query->result() as $row2)
{
echo $row2->ID;
}
}
Could it be done ?? Please Help me... Thanks in advance....
It is very hard to help you without seeing the tables and how you are relating one to the other (such as user_id).
What you should do is two queries. One query to get the data from table 1 of the vehicles you are interested in. Then run through the result set and create a simple array of those vehicles in php. Then do a second query using where_in to select all the rows that are in the chosen vehicles array.
Your method is bad because the number of db queries depends on the size of the result set of your first query. You might find your code trying to do hundreds of database queries.
If you show a diagram of your tables, I could write some example code for you.
Here are the docs for where_in: https://www.codeigniter.com/user_guide/database/query_builder.html#CI_DB_query_builder::where_in
I'm building a query to show items with user and then show highest Bid on the item.
Example:
Xbox 360 by james. - the highest bid was $55.
art table by mario. - the highest bid was $25.
Query
SELECT i, u
FROM AppBundle:Item i
LEFT JOIN i.user u
I have another table bids (one to many relationship). I'm not sure how can I include single highest bid of the item in the same query with join.
I know I can just run another query after this query, with function (relationship), but I'm avoiding to do that for optimisation reasons.
Solution
SQL
https://stackoverflow.com/a/16538294/75799 - But how is this possible in doctrine DQL?
You can use IN with a sub query in such cases.
I am not sure if I understood your model correctly, but I attempted to make your query with a QueryBuilder and I am sure you will manage to make it work with this example:
$qb = $this->_em->createQueryBuilder();
$sub = $qb;
$sub->select('mbi') // max bid item
->where('i.id = mbi.id')
->leftJoin('mbi.bids', 'b'))
->andWhere($qb->expr()->max('b.value'))
->getQuery();
$qb = $qb->select('i', 'u')
->where($qb->expr()->in('i', $sub->getDQL()))
->leftJoin('i.user', 'u');
$query = $qb->getQuery();
return $query->getResult();
Your SQL query may look something like
select i,u
from i
inner join bids u on i.id = u.item_id
WHERE
i.value = (select max(value) from bids where item_id = i.id)
group by i
DQL, I don't think supports subqueries, so you could try using a Having clause or see if Doctrine\ORM\Query\Expr offers anything.
To solve this for my own case, I added a method to the origin entity (item) to find the max entity in a list of entities (bids), using Doctrine's Collections' Criteria I've written about it here.
Your Item entity would contain
public function getMaxBid()
{
$criteria = Criteria::create();
$criteria->orderBy(['bid.value' => Criteria::ASC]);
$criteria->setLimit(1);
return $this->bids->matching($criteria);
}
Unfortunately, there's no way that i know to find the maximum bid and the bidder with one grouping query, but there's several techniques to making the logic work with several queries. You could do a sub select and that might work fine depending on the size of the table. If you're planning on growing to the point where that's not going to work, you're probably already looking at sharing your relational databases, moving some data to a less transactional, higher performance db technology, or denormalizing, but if you want to keep this implemented in pure MySQL, you could use a procedure to express in multiple commands how to check for a bid and optionally add to the list, also updating the current high bidder in a denormalized high bids table. This keeps the complex logic of how to verify the bid in one, the most rigorously managed place - the database. Just make sure you use transactions properly to stop 2 bids from being recorded concurrently ( eg, SELECT FOR UPDATE).
I used to ask prospective programmers to write this query to see how experienced with MySQL they were, many thought just a max grouping was sufficient, and a few left the interview still convinced that it would work fine and i was wrong. So good question!
i want to fetch data from database three tables all are linked together.
I'm facing problem, i have tried many methods to it like merge, unique and separate list.
following is the code.
<?php
$conn=new mysqli("localhost","root","","db");
$rows=$conn->query("select Account,Amount, event_name,event_description from donations
LEFT JOIN accounts
ON accounts.ID_Account=donations.ID_Account
LEFT JOIN events
ON events.event_id=donations.event_id ");
$rows1=$conn->query("SELECT Account from accounts");
while((list($Account, $Amount, $event_name,$event_description)=$rows->fetch_row()) and (list($Account)=$rows1->fetch_row()))
{
echo "<tr><td> $Account</td><td> $Amount </td><td>$event_name</td><td>$event_description</td></tr>";
}
?>
Now The problem is, it shows duplicate data from accounts and also I want it to be like if there is no donation $Amount for the account $Account it should not show donation in front of Account, but it is showing. is there any way i can make it working the way i want?
Many Thanks.
You are looking for some data hydration methods. Now you will get A * B * C = X rows with your resulting data because you are doing multiple joins and your resulting array from mysql will always have only one dimension and therefore a lot of duplicated data.
What you want is array (or object) with more than one dimension. I assume you want a resulting array with something like:
$result = array(
'account1' => array('event1', 'event2'),
'account1' => array('event3', 'event4', 'event5')
);
There are multiple solutions to this:
Write your own data hydration method to create a new array with values from your result
Do three single queries instead of one query with JOIN, then merge the results (can even be faster!)
Use doctrine (a php database abstraction layer) which can do exactly what you want without too much trouble.
If you start to code new app I would recommend 3.) to you:
http://doctrine-orm.readthedocs.org/en/latest/tutorials/getting-started.html
I am trying to replicate what would be a left join in MySql in Mongo. I have a collection named Clients and another collection name Orders.
In the clients collection is have:
client_PK, FirstName, LastName, Company
In the orders collection I have:
order_PK, client_fk, OrderDate, OrderAmount,
So i know that can use embedded documents but for the sake of this question i am looking to use the reference model.
My question is, using these two collections how would I construct a table or object similar to a left join in mysql? I know this is a document db not a relational db but im using sql language just to give you an idea of what im trying to accomplish. In MySql it would look like this:
SELECT * FROM orders LEFT JOIN clients ON clients.client_PK = orders.client_fk
with this i could now construct a table that looked like:
FirstName | LastName | Company | OrderDate | OrderAmount
then i could repeat the rows using a while loop to display all orders and display the clients name with the order. Again i know mongo isn't a relational db but i am assuming there is a way simulate a table using two collections.
Thank you.
You almost certainly want to be storing these data all in the same MongoCollection (even in just a denormalization collection).
If you absolutely can't do that, though, and if your set is small, you can do something similar to this (since you asked about PHP):
<?php
// gather orders
$orders = iterator_to_array($mongodb->orders->find());
$joinedOrders = array();
// gather clients
foreach ($db->clients->find() as $client) {
// iterate orders (like a left join)
foreach ($orders as $order) {
// make a "joinedOrders" record for each join match
if ($order['client_fk'] == $client['client_PK']) {
$joinedOrders[] = array_merge($order, $client);
}
}
}
// result is now in $joinedOrders
This is, however, almost always a bad idea. (-: You really should be denormalizing your data, or using a relational database to store/query relational data.
i am assuming there is a way simulate a table using two collections
MongoDB does not have any tool for doing this. You are basically going to have "roll your own" joins. At the basic level, this means that you will have to write nested for loops and build a result set in your code.
Doing this type of "extra logic" is pretty common in MongoDB because of the lack of joins. If you're seeing this pattern a lot, you may want to consider using SQL for part of your data.