I want to get all results from two tables akcii, feeds and after search throw them (now query just returns all records without any conditions for search), here is the query (mysql):
DB::query('SELECT id, title, text FROM (
SELECT id, title, text FROM `akcii` UNION ALL
SELECT id, title, body FROM `feeds`
) temp_table
ORDER BY `id` desc
LIMIT 0, 10')
Results are exacly that I need but after I can't convert it Collection?
If I call ->get() method I'm getting an error:
QueryException in Connection.php line 651:
SQLSTATE[HY000]: General error: 1096 No tables used (SQL: select *)
What am I doing wrong?
DB::query() method does not get any arguments, so the query you pass there is simply ignored. You're calling get() on an empty builder, which does not know what table to run the query on. Generated query is just SELECT *, hence the SQL error.
If you want that to work, you should call DB::select() method, e.g.:
$results = DB::select($your_query);
Still, what you'll get is an array, not a Collection object. If you want to make a collection out of it, do the following:
$collection = new Collection($results);
Related
I have a Laravel query that works when our DB is using our MySQL DB, but when I switch to our new PostgreSQL DB it stops working.
I am using Laravel's group by function as below:
$this->crud->groupBy('leads.id')
The whole query translated to mysql is below:
select count(*) as aggregate
from (select leads.* from leads
where leads.club_id in ('TR71') and
leads.deleted_at is null GROUP BY leads.id) as aggregate_table;
The error that is now giving is the following:
"SQLSTATE[42803]: Grouping error: 7 ERROR: column \"leads.name\" must appear in the GROUP BY clause or be used in an aggregate function (SQL: select count(*) as aggregate from (select \"leads\".* from \"leads\" where \"leads\".\"club_id\" in (TR71) and \"leads\".\"deleted_at\" is null group by \"leads\".\"id\") as \"aggregate_table\")"
It pretty much is asking me to list each column from the leads.* part of the query into the group by clause. So far I have tried listing each column but it is not efficient or good practice as we could always end up in the situation where we add more columns to the table
MySQL have an inconsisten behaviour with aggregate calculus.
The SQL standard require that all columns that are in the SELECT clause of a SELECT statement and are not involved in an aggregate function must be specified in the GROUP BY clause. This is probably the case of your subquery that limits the GROUP BY to only the leads.id column.
Excepts MySQL in which it is clearly a bug and returns false data, there is no other RDBMS that accepts such an inconsistent query syntax.... In this case, MySQL returns randomized data that you believe to be thruth !
Bellow SQL command runs perfectly :
select * from `product` group by `owner_name` order by `id` asc
When I translate above code in my Laravel project to get the same result :
Product::select('*')
->orderBy('id','asc')->groupBy('owner_name')
->get();
This laravel code returns me error that
SQLSTATE[42000]: Syntax error or access violation: 1055
'db1.product.id' isn't in GROUP BY (SQL: select * from product group
by owner_name order by id asc)
Problem is I have many duplicated records with slight differences on some of their columns. I need to get them by owner_name and only one time .
Edit your applications's database config file config/database.php
In mysql array, set strict => false to disable MySQL's strict mode
You have don't need to do 'select(*)', by default it will select all columns data.
Try this:
Product::orderBy('id','asc')->groupBy('owner_name')
->get();
And if you want to fetch selected column you can do like this:
Product::select(['column_1', 'column_2'])
->orderBy('id','asc')->groupBy('owner_name')
->get();
I am attempting to join two tables using the Laravel's query builder however I seem to be having an issue getting the desired result using the query builder, I can however get it quite simply using a raw SQL statement. I simply want to return all mod rows that have the corrosponding value in the tag column in the tags table.
Schema
--------------
mods
--------------
id - int - (primary key)
name - varchar
--------------
tags
--------------
id - int
modid - int - (primary key of its parent mod)
tag - varchar
Working SQL query
SELECT * FROM mod JOIN tags ON tags.tag LIKE '%FPS%'
Query Builder
DB::table('mods')
->join('tags', function ($join) {
$join->on('tags.tag', 'like', '%FPS%');
})
->get();
Currently this is telling me: Unknown column '%FPS%' in 'on clause' but I am unsure how else to structure this. I intend on adding more orOn clauses as well as I will want to get results on multiple tags but firstly I just want to get a single tag working.
Appreciate any help.
SELECT * FROM mod JOIN tags ON tags.tag LIKE '%FPS%'
Your query builder is refusing to generate this query because it's nonsense!
To work correctly, a JOIN clause needs to compare two columns for equality -- one column on each side of the join table. A JOIN clause that doesn't do this is functionally "downgraded" to a WHERE clause. In the case of this query, the two tables end up cross joined.
What you probably want is:
SELECT * FROM mod
JOIN tags ON tags.modid = mod.id
WHERE tags.tag LIKE '%FPS%';
$join->on('tags.tag', 'like', '%FPS%');
Try by replacing
$join->where('tags.tag', 'like', '%FPS%');
This because the on method waiting a name of a field not a query value if you want it to deal with it in this way, you should use DB::raw('%FPS%').
Maybe you are trying to do something like the following:
DB::table('mods')
->select(DB::raw('mods.id as modid, mods.name, tags.id as tagid, tags.tag'))
->join('tags', function ($join) {
$join->on('tags.modid', '=', 'mods.id');
})
->where('tags.tag', 'like', '%FPS%')
->get();
If you want to see what is run in the database use
dd(DB::getQueryLog())
to see what queries were run.
Try this
Thank you
We have modeled self-referencing relations in our User model using belongsToMany(). Users can be agent or seller for each other - so we definer seller() and agents()
Now we are using https://github.com/Nayjest/Grids which needs a query to the grid.
In the grid we want for example to display a seller's agents.
Currently we are using a hand-crafted query for that - but we would like to pull the logic from the model.
So what we need is the query (as query builder object) which is executed when fetching
$seller = Auth::user(); // or any other instance of User
$seller->agents
We tried
$query = $seller->newQuery()->where('laravel_reserved_1.id', '=', $seller->id);
return $user->agents()->getRelationQuery($query, $query);
without luck.
EDIT
Trying $seller->agents()->getQuery() we get
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous
(SQL: select * from `users` inner join `user_connections` on
`users`.`id` = `user_connections`.`user_id`
where `user_connections`.`related_user_id` = 2 and
`user_connections`.`type` = agent order by `id` asc
limit 15 offset 0)
Turns out it is just
$user->agents()->getQuery()
We had a column "id" in the grid which led to the ambiguous query later in the process.
I have 2 Tables:
region: region_id,name,state_id
state: state_id,name
I want both names in my result, state.name renamed to statename.
So far I got this:
$select = $select->from(array('r' => 'region'))->join(array('s' => 'state'),
'r.state_id = s.state_id',array("statename" =>"r.name"));
which results in following query:
SELECT `r`.*, `r`.`name` AS `statename` FROM `region` AS `r`
INNER JOIN `state` AS `s` ON r.state_id = s.state_id
So i just need to change r.name AS statename to s.name AS statename.
But i cant get it to work. If i change the last part of the select to array("statename" =>"s.name"), i get an error
Select query cannot join with another table
So how can i rename a field in the joining table?
You have to remove the integrity check.
$table = new self();
$select = $table->select()->setIntegrityCheck(false);
$select = $select->from(array('r' => 'region'))->join(array('s' => 'state'),'r.state_id = s.state_id',array("statename" =>"s.name"));
The integrity check is there to make sure your query is not going to use columns from another table, so Zend_Db_Table_Row objects can be updated, saved or deleted. If you remove the integrity, you're telling Zend that you know what you're doing and you want to use columns from another table.
Here's a brief explanation from documentation:
The Zend_Db_Table_Select is primarily used to constrain and validate
so that it may enforce the criteria for a legal SELECT query. However
there may be certain cases where you require the flexibility of the
Zend_Db_Table_Row component and do not require a writable or deletable
row. for this specific user case, it is possible to retrieve a row or
rowset by passing a FALSE value to setIntegrityCheck(). The resulting
row or rowset will be returned as a ‘locked’ row (meaning the save(),
delete() and any field-setting methods will throw an exception).