As far as the SQL side of things goes, there is opportunity to optimize, but it depends on what you want to optimize around. If you are seeking to simplify queries or speed up performance, denormalization is one way to achieve this. For example, you could include the client_id in the comment table in addition to the blog_id given that it appears that blogs can have only one associated client_id. Once you do that, the query above becomes:
select comments.* from comments
inner join users on users.client_id = comments.client_id
where users.user_id = X;
This is less complex, and depending on the size of the tables could have some performance benefit. The tradeoff is that you will end up with a somewhat more complex data model with redundant data across tables making it potentially harder to maintain data integrity.
Note, in your original example above, it is possible to simplify the query. without denormalizing. You aren't actually using any of the "clients" table data in the result, so including it in the join is extraneous given that the "users" table includes the client_id and can be joined directly to the blogs table.
For the NoSQL side of things, there is a lot of variability across platforms with respect to how they treat the individual fields within a document and how they can be indexed and/or made searchable. For example, you could still keep each post as a separate document and, in MongoDB at least, you could index the client_id field to make it faster to search for and retrieve the right posts, but the optimal approach might be different on another platform.
One concern with building a large document that contains all of the blog posts and comments for the client, as you suggest above, is that you could run into challenges with performance. On a query, you might have to retrieve the whole document, move it over the network, and navigate through the document to get to the item you want. This could be slow. If multiple users are adding comments at the same time, you could run into more lag as the requests are queued waiting for write locks to be released.
Decomposing into multiple documents/collections with MongoDB, for example, carries, the additional complexity of having to run multiple queries to retrieve the item you want, but it lets you read and update at a smaller grain and could result in improved performance and probably lower overall complexity in your code as you no longer need to manage the entire set of blog posts for the client as one large, complex, collection.