I'm working on a project where I have many users, and a user has many posts. I'm trying to get the users that have a post count over a certain threshold, but the query I'm using doesn't seem to work.
User.where(id: user_ids)
.where(has_posts: true)
.joins(:posts)
.group('users.id')
.having('COUNT(posts.id) >= user.post_threshold')
However with this query I get Unknown column posts.id in 'having clause':
Any help on how to fix this would be greatly appreciated.
You don't need having for that, a simple where will serve you well:
User.
where(id: user_ids).
where(has_posts: true).
where('COUNT(posts.id) >= users.post_threshold').
joins(:posts).
group('users.id')
Edit: On some databases, you might need to include the aggregation in a select, adding this line to the chain:
.select('*, COUNT(posts.id)')
You can use the posts.* notation, at least in Postgres, don't know about mysql.
User.where(id: user_ids)
.where(has_posts: true)
.joins(:posts)
.group(:id)
.having('COUNT(posts.*) >= users.post_threshold')
Related
i'm getting a really confused problem... i'm triying to do a query:
SELECT ordenes_servicio.idorden, estatus_orden.descripcion AS estatus, tipo_orden.descripcion AS tipo_orden, usuario.nombre, ordenes_servicio.nombres_cliente, ordenes_servicio.fecha_asig
FROM ordenes_servicio
INNER JOIN estatus_orden ON ordenes_servicio.idestatus_orden = estatus_orden.idestatus_orden
INNER JOIN tipo_orden ON ordenes_servicio.idtipo_orden = tipo_orden.idtipo_orden
INNER JOIN usuario ON ordenes_servicio.id = usuario.id
ORDER BY ordenes_servicio.idorden DESC
The problem is that when i try to run it, it say
ER_BAD_FIELD_ERROR: Unknown column 'ordenes_servicio.idusuario' in
'on clause'
But if you look at the query, there is no 'ordenes_servicio.idusuario', and yes there was, but i update my tables, both of them, and it is like the query is still triying to get that column.
When i execute the query in my MySQL Workbench it work, but dont when i try to run it in my application... Someone can help me? :/
Note: my "app" is actually a REST API in typescript, and i'm using express library
I got the answer... if can help a beginner like me someday. Im actually executing three querys, and there was one of then that still had "ordenes_servicio.idusuario"... that's all.. So check your querys!
Beginner error...
I am trying to figure out the correct syntax to add an AND operator to the following Eloquent Raw query in which I am querying a MySQL (5.7.9) table's JSON field. In doing so, I would like to be able to have case insensitivity capabilities.
After doing initial research as to how to achieve this, I have my code working in a basic way like this:
$users = User::whereRaw('lower(info_json->"$.full_name") like lower(?)', ["%{$user_name}%"])
But my goal is to add an AND operator to narrow down my results further with a non-JSON varchar column.
I have tried this (and other variations without success):
$users = User::whereRaw('lower(info_json->"$.full_name") like lower(?)', 'and user_type = admin', ["%{$user_name}%"])
Which gives me an error:
"Array to string conversion"
I have also tried:
$users = User::whereRaw('lower(info_json->"$.full_name") like lower(?) and user_type = admin', ["%{$user_name}%"])
Which give me the following error:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_type' in 'where clause'"
Other similar variations that have not resulted in errors have yielded too many or too few results.
How can I successfully adjust my syntax to query an additional non-JSON field with the correct results? Also, is doing a raw query like this the most effective way to do so with Eloquent, MySQL (5.79) and Laravel 5.6?
Thank you for any and all help/direction offered! :)
I think you should do something like
$users = User::where(DB::raw('lower(info_json->"$.full_name")', 'like', DB::raw('lower(%{$user_name}%)'))
->where('user_type', '=', 'admin')
Probably I have some sintax error but main idea is to use DB::raw to help you with your query.
I figured it out. My syntax should have looked like this:
$users = User::whereRaw('lower(info_json->"$.full_name") like lower(?)', ["%{$user_name}%"])->where('user_type', '=', 'admin')->get();
Thanks to those who assisted with this! Like a lot of syntax/coding problems, taking a little break from it helped me to figure it out quite quickly when I returned to it.
Can anyone please advise me on this error...
The database has 40,000 news stories but only the fields 'story' is large,
'old' is a numeric value 0 or 1,
'title' and 'shortstory' are very short or NULL.
any advice appreciated. This is the result of running a search database query.
Error: MySQL client ran out of memory
Statement: SELECT news30_access.usehtml, old, title, story, shortstory, news30_access.name AS accessname, news30_users.user AS authorname, timestamp, news30_story.id AS newsid FROM news30_story LEFT JOIN news30_users ON news30_story.author = news30_users.uid LEFT JOIN news30_access ON news30_users.uid = news30_access.uid WHERE title LIKE ? OR story LIKE ? OR shortstory LIKE ? OR news30_users.user LIKE ? ORDER BY timestamp DESC
The simple answer is: don't use story in the SELECT clause.
If you want the story, then limit the number of results being returned. Start with, say, 100 results by adding:
limit 100
to the end of the query. This will get the 100 most recent stories.
I also note that you are using like with story as well as other string columns. You probably want to be using match with a full text index. This doesn't solve your immediate problem (which is returning too much data to the client). But, it will make your queries run faster.
To learn about full text search, start with the documentation.
I have been getting an error "Unknown column 'guests_guest.id' in 'field list'" when i try to run the following:
SELECT guests_guest.id
FROM `guests_guest` full join
guests_guest_group
on guests_guest.id=guests_guest_group.guest_id
All the column& table names are correct. in fact, running just
SELECT guests_guest.id
FROM `guests_guest`
works just fine. I suspect there is a syntax issue I am missing. what am I doing wrong?
try:
SELECT gg.id
FROM `guests_guest` as gg
join guests_guest_group as ggg
on ggg.guest_id=gg.id
assuming guests_guest_group does not have an id column.
full join ?
Have you tried simply removing the full?
This not Oracle, it's MySQL, right? AFAIK, FULL JOIN is not implemented yet in MySQL.
The parser (because "full' is not a keyword it knows), evaluates your query as:
SELECT guests_guest.id
FROM guests_guest AS full <--- crucial note
JOIN guests_guest_group
ON guests_guest.id = guests_guest_group.guest_id
After that, guests_guest is not a name it knows, but it uses full as an alias for table guests_guest. That's why this error is produced.
If you really need FULL JOIN and not (INNER) JOIN, then search SO for how to implement FULL JOIN in MYSQL.
#rockerest: I guest so.
Two things I'd look at:
Spelling... I am a fast typer, but sometimes my fingers are dyslexic. Worst case, do a describe on each table and check column names against each other. Or, use the system-confessed column names and copy/paste.
Aliases... but, someone else has mentioned that.
So I guessed just one thing.
I am having a problem with the following query(if this is a duplicate question then i'm terribly sorry, but i can't seem to find anything yet that can help me):
SELECT d.*, GROUP_CONCAT(g.name ORDER BY g.name SEPARATOR ", ") AS members
FROM table_d AS d LEFT OUTER JOIN table_g AS g ON (d.eventid = g.id)
WHERE members LIKE '%p%';
MySQL apparently can't handle a comparison of GROUP_CONCAT columns in a WHERE clause.
So my question is very simple. Is there a workaround for this, like using sub-query's or something similar? I really need this piece of code to work and there is not really any alternative to use other than handling this in the query itself.
EDIT 1:
I won't show the actual code as this might be confidential, I'll have to check with my peers. Anyway, I just wrote this code to give you an impression of how the statement looks like although I agree with you that it doesn't make a lot of sense. I'm going to check the answers below in a minute, i'll get back to you then. Again thnx for all the help already!
EDIT 2:
Tried using HAVING, but that only works when i'm not using GROUP BY. When I try it, it gives me a syntax error, but when I remove the GROUP BY the query works perfectly. The thing is, i need the GROUP BY otherwise the query would be meaningless to me.
EDIT 3:
Ok, so I made a stupid mistake and put HAVING before GROUP BY, which obviously doesn't work. Thanks for all the help, it works now!
Use HAVING instead of WHERE.
... HAVING members LIKE '%peter%'
WHERE applies the filter before the GROUP_CONCAT is evaluated; HAVING applies it later.
Edit: I find your query a bit confusing. It looks like it's going to get only one row with all of your names in a single string -- unless there's nobody in your database named Peter, it which case the query will return nothing.
Perhaps HAVING isn't really what you need here...
Try
SELECT ...
...
WHERE g.name = 'peter'
instead. Since you're just doing a simple name lookup, there's no need to search the derived field - just match on the underlying original field.
GROUP_CONCAT is an aggregate function. You have to GROUP BY something. If you just want all the rows that have %peter% in them try
SELECT d.*, g.name
FROM table_d AS d
LEFT OUTER JOIN table_g AS g
ON (d.eventid = g.id)
WHERE g.name LIKE '%peter%';