Mysql,Php,Laravel checkbox error - php

I have the next question. How can I solve that problem? I have two tables vehicles and vehicles_extras. In the first table have a lot of columns. In the second table I have only 4 columns:
id, vehicle_id, vehicletype, vehicle_extra
The id is autoincrement, the vehicle_id is from the first table the id column, the 'vehicletype' is a string, type of the vehicle, the vehicle_extra is the number of the extras.
So I have a search form,where is the extras are checkboxes, extra[]. In a web.php I have this code:
$data1=DB::table('vehicles_extras')->where('vehicletype','$vt')->where('vehicle_extra',$extras);
....
if(Input::has('extras'))
$query->union($data1);
$data=$query->get();
for that I get error:
SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns (SQL: (select count(*) as aggregate from vm_vehicles where vehicletype = car) union (select * from vm_vehicles_extras where vehicletype = car and vehicle_extra = 2))
But ok, let's say it's working, but I have array with more values, so I want to use whereIn .
Any idea? I use Laravel 5.3.

First, you have to create one-to-many relation between vehicles and vehicles_extras.
Add the following relation in your Vehicle model:
public function vehicleExtras()
{
return $this->hasMany('App\VehicleExtra');
}
Then you can query it as:
Vehicle::whereHas('vehicleExtras', function ($q) use($extra) {
$q->where('vehicletype', 'car')
->whereIn('vehicle_extra', $extra);
})->get();

Related

groupBy a row that can have one or both of two columns non-null

I have 3 tables:
Shifts {vehicled_id, user_id, subdriver_id)
Users {user_id, subdriver_id)
Vehicles {vehicle_id}
I want to group Shifts when I join with Users and Vehicles but some shifts only have user_id or subdriver_id and some have both.
This is the picture of shifts tables.
The result I want is a groupBy of vehicle_id and:
If it has only user_id or subdriver_id it will return {user_id, vehicle_id, shift_id (it can be an array)}
or {subdriver_id, vehicle_id, shift_id (it can be an array)}.
If it has both user and subdriver it will return {user_id, vehicle_id, shift_id(it can be array)}
shift_id is based on user_id and vehicle_id or subdriver_id and vehicle_id.
How can I groupBy and return a result like this?
You have to use CASE statement which goes through multiple conditions and return a value based on respective condition.
DB::table('shifts')
->select(DB::raw('CASE WHEN shifts.user_id IS NULL THEN shifts.subdriver_id WHEN shifts.subdriver_id IS NULL THEN shifts.user_id ELSE shifts.user_id END as user_id, shifts.vehicle_id, GROUP_CONCAT(shifts.id) as shift_id'))
->leftJoin('users as u1','u1.id','shifts.user_id')
->leftJoin('users as u2','u2.subdriver_id','shifts.subdriver_id')
->groupBy('shifts.vehicle_id')
->get();

How to aggregate query on related table's field in Laravel?

I have a One To Many (Inverse) relation on my laravel 5.4 application. There are two models Sale and Vehicle which are related and associated with the scene.
The relation on the Sale model is :
public function vehicle()
{
return $this->belongsTo('App\Models\Vehicle','vehicle_id');
}
Table sales has following fields :
id, vehicle_id, date_time, status etc.
Table vehicles has following fields :
id, reg_number, volume, status etc.
What I want is, sum of the field 'vehicles.volume' of Sale records within the search conditions.
I have tried some methods like the following one:
$query = Sale::where('status', 1);
$query = $query->where('date_time', '<', "2017-05-10 10:10:05");
$totalVolume = $query->whereHas('vehicle')->sum('vehicles.volume');
and it resulted in the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'vehicles.volume' in 'field list' (SQL: select
sum(vehicles.volume) as aggregate from sales where status = 1
and date_time < "2017-05-10 10:10:05" and exists (select * from vehicles where sales.vehicle_id =
vehicles.id))
hopefully waiting for a solution to 'get the sum of the volume of the sales' using eloquent query.
Edited
You need to use a join before summing the vehicles.volume column
$totalVolume = Sale::where('status', 1)
->where('date_time', '<', "2017-05-10 10:10:05")
->join('vehicles', 'vehicles.id', '=', 'sales.vehicle_id')
->select(DB::raw('sum(vehicles.volume) as total_volume');
select sum(volume) as aggregate from vehicles INNER JOIN sales ON vehicles.id=sales.vehicle_id

Select entities assuming related entity does not exist

My entity (Product) has a unidirectional many-many relation with another entity (Company) called deletedByCompanies.
I wish to select all Products that has not been deleted by a particular company. That is all products that are not connected through that many-many relation.
Tried:
$this->em->getRepository(Product::class)->createQueryBuilder('t')
->leftJoin('t.deletedByCompanies', 'deletedCompany')
->andWhere('deletedCompany.id not in (:companyId)')
->setParameter('companyId', [$companyId]);
But this simply does not return anything.
Schema is pretty straghtforward:
Product:
id: int PK
Company:
id: int PK
DeletedProducts
product_id: int FK
company_id: int FK
Entity definition in Product class:
/**
* #var Company[]
* #ORM\ManyToMany(targetEntity="Company", indexBy="id")
* #ORM\JoinTable(name="DeletedProducts")
*/
protected $deletedByCompanies;
I think you can solve your problem with a NOT EXISTS clause on the deletedby table.
In the SQL dialect:
SELECT * FROM product p WHERE NOT EXISTS
(SELECT * FROM DeletedProducts d WHERE p.id=d.product_id AND company_id = 2 );
In the Doctrine2 DQL, we haven't the entity DeletedProducts so we have to do a bit more stuff like:
$qb = $this->em->getRepository("AcmeDemoBundle:Product")->createQueryBuilder('t')
->Join('t.deletedByCompanies', 'deletedCompany')
->andWhere('deletedCompany.id in (:companyId)')
->andWhere("p=t");
$mainQb = $this->em->getRepository("AcmeDemoBundle:Product")->createQueryBuilder('p');
$mainQb->where($mainQb->expr()->not($mainQb->expr()->exists($qb->getDQL())));
$mainQb->setParameter('companyId', [$companyId]);
var_dump($mainQb->getQuery()->getSql());
$res =$mainQb->getQuery()->execute();
Let me know if I don't understand your problem.
Hope this help
I'm not familiar with Doctrine, but I'm trying to help with some SQL knowledge. Following query should do what you want:
SELECT DISTINCT Product.* FROM Product
LEFT JOIN DeletedProducts on product_id = product.id
WHERE product_id IS NULL OR product_id !=
ALL( SELECT product_id FROM DeletedProducts WHERE company_id = 2 )
Some Explanation...
DISTINCT: Nessacary keyword to prevent redundancy. The same product can appear multiple times in the result of the Left Join if it is deleted by . DISTINCT eliminates those duplicates.
WHERE product_id IS NULL: The Left Join will also list the products which are not related to any company over the "DeletedProducts"-table. Since there is no relation the fields product_id and company_id are NULL.
OR product_id != ALL( [...] ): Now that we have got the products which aren't deleted by any company, we need additionally those which aren't deleted by a particular company. So we use an OR with a subquery which selects all deleted products of a certain company (e.g. company id = 2 as in the code example). Since we want to have the not-deleted products we have to use the "!="-Operator.
I hope this helps a little. Now it's up to you to "translate" the query for the usage within Doctrine.

Where query from other table + Doctrine

I'm stuck with creating a where query. I have table item with item_id, item_title, item_description, item_created, item_approved. I also have a table article with PK item_id (from item table) and article_body. The last table is media with medium_id, item_id (FK), medium_url and medium_type.
Now I would like to select all the data from media where item.item_approved is not NULL and where item.item_id ins't present in the article table.
Now I can select all the data from media where item.item_approved is not NULL. But now I need to do another check that he doesn't select the items that are also in article table. My query so far:
$repository = $entityManager->getRepository('VolleyScoutBundle:Media');
$query = $repository->createQueryBuilder('m')
->join('m.item', 'i')
->where('i.itemApproved is not NULL')
->getQuery();
Most likely that you must use 2 queries. With JOINs it can not be done.

MySQL inner join table gives repetaed value from unique table

Hello i have two tables with a PK---->FK Relationship in InnoDB Engine---->MySQL&PHP
The Relationship is one---->many between first table which is 'Properties' and second
table which is 'propertyimages'. every row in first table is unique but in second table
every row of first table has got many rows in second table How can i **SELECT unique row from
first table and all info about first table from second table here is my query:
SELECT DISTINCT properties.PropertyName,
properties.PropertyStatus,
propertyimages.PropertyImageID,
propertyimages.ImagePath
FROM properties
INNER JOIN propertyimages
ON properties.PropertyImageID=propertyimages.PropertyImageID
AND propertyimages.PropertyImageID=8;
it gives result:
PropertyName PropertyStatus Propertyid property Image Path
Appartment For Lease 8 upload/hydrangeas.jpg
Appartment For Lease 8 upload/jelsh.jpg
Appartment For Lease 8 upload/penguins.jpg
Appartment For Lease 8 upload/tulips.jpg
In this result the PropertyName and PropertyStatus is Repeated but i want a
unique as its stored in the first tableThe propertyName and PropertyStatus
belongs to first table.The Propertyid and PropertyImagepath belings to second table.
unfortunately a join will create a record for each element found in table 2 with a matching parent element (id 8) in the first table.
you could use a GROUP BY id 8 on the first table field, but you may not get all the results you want since it will take the first image only.
could you restructure your process so that when it comes to the images (and thier display) you could just run a single query to get every image related to property 8
you could always use a nested query (presuming you're looking to display images on a page for a property, etc)
$query1 = mysql_query("SELECT Propertyid, PropertyName, PropertyStatus FROM properties WHERE (search criteria)");
if (mysql_num_rows($query1) > 0) {
while ($q1Row = mysql_fetch_array($query1)) {
// Insert property specific data here before you display the images
echo $q1Row['PropertyName']."<br>\n";
echo $q1Row['PropertyStatus']."<br>\n";
$query2 = "SELECT PropertyImageID, ImagePath FROM propertyimages WHERE PropertyImageID='".$q1Row['Propertyid']."'"
if (mysql_num_rows($query2) > 0) {
while ($q2Row = mysql_fetch_array($query2)) {
// add code here to do whatever you want with the images
echo '<image src="'.$q2Row['ImagePath'].'"><br>\n';
}
}
}
}
}
it would also help to know your DB structure .. i'd imagine you'd want something like this
table 1 (properties)
PropertyID (Primary Key)
PropertyName
PropertyStatus
table 2 (propertyImages)
ImageID (Primary Key)
PropertyID (many to one reference to PropertyID in table 1)
ImagePath
I may be a bit oblivious to the FK method so if there is a lesson here for me as well, i'd love to hear what input you have.
you are one step away from the solution, you just need to select from second table and then for first so you will have all you result matched
SELECT DISTINCT properties.PropertyName,
properties.PropertyStatus,
propertyimages.PropertyImageID,
propertyimages.ImagePath
FROM propertyimages
INNER JOIN properties
ON propertyimages.PropertyImageID = properties.PropertyImageID
AND propertyimages.PropertyImageID=8;
You could achieve this with GROUP_CONCAT. But I also think, it is better to make two queries. Nothing wrong with that.
SELECT DISTINCT properties.PropertyName,
properties.PropertyStatus,
propertyimages.PropertyImageID,
GROUP_CONCAT(propertyimages.ImagePath)
FROM properties
INNER JOIN propertyimages
ON properties.PropertyImageID=propertyimages.PropertyImageID
AND propertyimages.PropertyImageID=8;
GROUP BY propertyimages.PropertyImageID

Categories