I am sure this is a simple syntax issue and I am taking a chance by asking the question but I just can't figure it out on my own. I have a functioning Filterrific :sorted_by selector, works great, sorts my Ticket records according to field values text and date types.
My Tickets table joins to a Comments table in a one-to-many relationship, and I am trying to sort a set of Ticket records by the newest update date from its associated Comment records.
Initially my solution was to add this to my scope:
when /*comment_date/
order("tickets.comments.updated_at #{direction}").includes(:comments).references(:comments)
The behavior is perplexing, my data is not being sorted across pagination, but perhaps coincidentally the records on a selected page are in order. I would love to post the backend SQL but work constraints do not allow it, so I hope I am not scolded or chastised for not providing enough evidence of my research.
Trying to find examples of Filterrific solutions is tough, after awhile I keep seeing the same posts on different websites. I have read every open and closed issue on GitHub, and the 79 or so tagged questions here on SO. It's so frustrating because I am sure there is a simple, logical solution but I can't see it!
As always, thank you for your time. I consider your attention a privilege, not a right, and I value any guidance.
Use joins instead of includes that way, the table is in your query.
...joins(:comments).references(:comments)
Same as what #thesecretmaster mentioned. Just making a post so you can close this
I wonder if there's a way to prevent the creation of objects that contain old ansi sintax of join, maybe server triggers, can anyone help me?
You can create a DDL trigger and mine the eventdata() XML for the content of the proc. If you can detect the old syntax using some fancy string-parsing functions (maybe looking for commas between known table names or looking for *= or =*), then you can roll back the creation of the proc or function.
First reaction - code reviews and a decent QA process!
I've had some success looking at sys.syscomments.text. A simple where text like '%*=%' should do. Be aware that long SQL strings may be split across multiple rows. I realise this won't prevent objects getting in there in the first place. But then DDL triggers won't tell you how big your current problem is.
Although I fully understand your effort, I believe that this type of actions is the wrong way of getting where you want. First of all, you might get into serious trouble with your boss and, depending of where you work, get fired.
Second, as stated before, doing code reviews, explaining why the old syntax sucks. You have to have a decent reason why one should avoid the *= stuff. 'Because you don't like it' is not a feasible argument. In fact, there are quite some articles around showing that certain problems are just not solvable using this type of syntax.
Third, you might want to point out that separating conditions into grouping (JOIN ... ON...) and filtering conditions (WHERE...) increases the readability and might therefore be an options.
Collect your arguments and convince your colleagues rather than punishing them in quite an arrogant way.
I'm currently writing an application that uses SQLite. SQLite doesn't have the ON UPDATE function for timestamps so I wrote my first trigger for it. Then I wrote a trigger to add the current timestamp on the modified and created fields on an insert.
The problem came when I went and deleted the setting of the modified/created fields for the insert. I felt like I was hiding something from developers that might see my code in the future. It could be a source of confusion.
How will they know that the sql is coming from a trigger. Should I comment it? Is it bad practice?
As a rule of thumb, triggers are meant to implement SQL functional rules, such as inclusions, exclusions, partitions etc.
This kind of thing belongs to the model and should be implemented as triggers whenever it is possible. It has to be delivered with the database otherwise the model would be broken.
Regarding to your case, it is more a hack than anything. If you can't do differently, do it and then add a comment like you said. But it should remain an exception.
Keep in mind that almost everything a trigger is doing could be done at the application layer (whichever you want)
Good observation. There are some things only triggers can do. However I suggest that if there is any alternative to using a trigger then use the alternative. I'm not familiar with SQLite, but in any other database I would use a DEFAULT rather than a trigger to timestamp a new record. To capture updated date I would enclose this in a stored procedure, or whatever database side logic you have (kind of what RandomUs1r suggested). I might consider a trigger but only for very basic operations.
You are correct that triggers can be confusing and difficult to debug.
"I felt like I was hiding something from developers..." - this is a very good point. I've came across many developers who use ##Identity and were genuinely shocked that if somebody put a trigger on the table which inserted another row, they'd end up with the wrong identity. (As opposed to SCOPE_IDENTITY() - I know these are sql server specific, but that's pretty much all I know...)
It is hidden - other than documentation I'm not sure you can make it more visible either.
Which is why many avoid them where possible - I guess if there's no easy way around using them in some cases then as long as its well documented, etc. I think like cursors, although scorned by many they can be very powerful and useful...but if they can be avoided probably for the best.
On the code that modifies the record, to get the current timestamp... in SQLLite, try:
DATETIME('NOW')
With beta4 and latest beta5 the DB-Feature-Implementation appears to have pretty much finished. There's a couple of tutorials out there how to handle a single Database using the TableGateway Pattern, but it appears there is none for handling M-N-Relationships.
In ZF1 we had findDependantRowset() on the TableGateway which was kind of dirty, as this simply was a second Query to the databse which pretty much isn't always neccessary.
In ZF2 i expected there to be a way to have good Joins mapping to specified models, but i can't find anything within the code. Maybe i'm blind, maybe there really isn't anything like this.
Has anyone of you managed to handle joins and models all together in ZF2? If so, please be so kind to instruct me how to do it, hint me to specific points of the documentation or link me some blogpost to one who has done it.
Thanks in advance guys!
The obvious solution if you need a generic solution is to use Doctrine ORM or Propel.
If you want to use Zend\Db, then within your concrete table gateway classes, you should write a specific method that retrieves the correct rows from the linked table. This way you can ensure that the SQL is optimised for the query that you need.
I have been working on sql server and front end coding and have usually faced problem formulating queries.
I do understand most of the concepts of sql that are needed in formulating queries but whenever some new functionality comes into the picture that can be dont using sql query, i do usually fails resolving them.
I am very comfortable with select queries using joins and all such things but when it comes to DML operation i usually fails
For every query that i never done before I usually finds uncomfortable with that while creating them. Whenever I goes for an interview I usually faces this problem.
Is it their some concept behind approaching on formulating sql queries.
Eg.
I need to create an sql query such that
A table contain single column having duplicate record. I need to remove duplicate records.
I know i can find the solution to this query very easily on Googling, but I want to know how everyone comes to the desired result.
Is it something like Practice Makes Man Perfect i.e. once you did it, next time you will be able to formulate or their is some logic or concept behind.
I could have get my answer of solving above problem simply by posting it on stackoverflow and i would have been with an answer within 5 to 10 minutes but I want to know the reason. How do you work on any new kind of query. Is it a major contribution of experience or some an implementation of concepts.
Whenever I learns some new thing in coding section I tries to utilize it wherever I can use it. But here scenario seems to be changed because might be i am lagging in some concepts.
EDIT
How could I test my knowledge and
concepts in Sql and related sql
queries ?
Typically, the first time you need to open a child proof bottle of pills, you have a hard time, but after that you are prepared for what it might/will entail.
So it is with programming (me thinks).
You find problems, research best practices, and beat your head against a couple of rocks, but in the process you will come to have a handy set of tools.
Also, reading what others tried/did, is a good way to avoid major obsticles.
All in all, with a lot of practice/coding, you will see patterns quicker, and learn to notice where to make use of what tool.
I have a somewhat methodical method of constructing queries in general, and it is something I use elsewhere with any problem solving I need to do.
The first step is ALWAYS listing out any bits of information I have in a request. Information is essentially anything that tells me something about something.
A table contain single column having
duplicate record. I need to remove
duplicate
I have a table (I'll call it table1)
I have a
column on table table1 (I'll call it col1)
I have
duplicates in col1 on table table1
I need to remove
duplicates.
The next step of my query construction is identifying the action I'll take from the information I have.
I'll look for certain keywords (e.g. remove, create, edit, show, etc...) along with the standard insert, update, delete to determine the action.
In the example this would be DELETE because of remove.
The next step is isolation.
Asnwer the question "the action determined above should only be valid for ______..?" This part is almost always the most difficult part of constructing any query because it's usually abstract.
In the above example you're listing "duplicate records" as a piece of information, but that's really an abstract concept of something (anything where a specific value is not unique in usage).
Isolation is also where I test my action using a SELECT statement.
Every new query I run gets thrown through a select first!
The next step is execution, or essentially the "how do I get this done" part of a request.
A lot of times you'll figure the how out during the isolation step, but in some instances (yours included) how you isolate something, and how you fix it is not the same thing.
Showing duplicated values is different than removing a specific duplicate.
The last step is implementation. This is just where I take everything and make the query...
Summing it all up... for me to construct a query I'll pick out all information that I have in the request. Using the information I'll figure out what I need to do (the action), and what I need to do it on (isolation). Once I know what I need to do with what I figure out the execution.
Every single time I'm starting a new "query" I'll run it through these general steps to get an idea for what I'm going to do at an abstract level.
For specific implementations of an actual request you'll have to have some knowledge (or access to google) to go further than this.
Kris
I think in the same way I cook dinner. I have some ingredients (tables, columns etc.), some cooking methods (SELECT, UPDATE, INSERT, GROUP BY etc.) then I put them together in the way I know how.
Sometimes I will do something weird and find it tastes horrible, or that it is amazing.
Occasionally I will pick up new recipes from the internet or friends, then use parts of these in my own.
I also save my recipes in handy repositories, broken down into reusable chunks.
On the "Delete a duplicate" example, I'd come to the result by googling it. This scenario is so rare if the DB is designed properly that I wouldn't bother keeping this information in my head. Why bother, when there is a good resource is available for me to look it up when I need it?
For other queries, it really is practice makes perfect.
Over time, you get to remember frequently used patterns just because they ARE frequently used. Rare cases should be kept in a reference material. I've simply got too much other stuff to remember.
Find a good documentation to your software. I am using Mysql a lot and Mysql has excellent documentation site with decent search function so you get many answers just by reading docs. If you do NOT get your answer at least you are learning something.
Than I set up an example database (or use the one I am working on) and gradually build my SQL. I tend to separate the problem into small pieces and solve it step by step - this is very successful if you are building queries including many JOINS - it is best to start with some particular case and "polute" your SQL with many conditions like WHEN id = "123" which you are taking out as you are working towards your solution.
The best and fastest way to learn good SQL is to work with someone else, preferably someone who knows more than you, but it is not necessarry condition. It can be replaced by studying mature code written by others.
Your example is a test of how well you understand the DISTINCT keyword and the GROUP BY clause, which are SQL's ways of dealing with duplicate data.
Examples and experience. You look at other peoples examples and you create your own code and once it groks, you don't need to think about it again.
I would have a look at the Mere Mortals book - I think it's the one by Hernandez. I remember that when I first started seriously with SQL Server 6.5, moving from manual ISAM databases and Access database systems using VB4, that it was difficult to understand the syntax, the joins and the declarative style. And the SQL queries, while powerful, were very intimidating to understand - because typically, I was looking at generated code in Microsoft Access.
However, once I had developed a relatively systematic approach to building queries in a consistent and straightforward fashion, my skills and confidence quickly moved forward.
From seeing your responses you have two options.
Have a copy of the specification for whatever your working on (SQL spec and the documentation for the SQL implementation (SQLite, SQL Server etc..)
Use Google, SO, Books, etc.. as a resource to find answers.
You can't formulate an answer to a problem without doing one of the above. The first option is to become well versed into the capabilities of whatever you are working on.
The second option allows you to find answers that you may not even fully know how to ask. You example is fairly simplistic, so if you read the spec/implementation documentaion you would know the answer right away. But there are times, where even if you read the spec/documentation you don't know the answer. You only know that it IS possible, just not how to do it.
Remember that as far as jobs and supervisors go, being able to resolve a problem is important, but the faster you can do it the better which can often be done with option 2.