Non-Trivial Data-Query in Grails - sql

imagine the following problem in grails
you have some kind of audit trail domain class with numeric properties. For instance a class in which the current burndown value of your scrum project is written:
class burndown {
Date createDate
int value
}
Your projects uses this class to store the current burndown value each time you update a task - this means several times a day.
Now you want to plot a diagram with the last stored value for each day.
An SQL statement for this could look something like
select
*
from
table
where
id in (
select
max(id)
from
table
group by
TO_CHAR(create_date,'yyyyddmm')
)
Now my question: how do you do such a query in grails?
If I have to use such an SQL statement, how to I avoid to put the table and column names hard coded in the statement?
PS: this code hasn't been tested. just written down from my mind... but I guess you feel what I want to ask

For starters you'll most likely want to rename createDate to dateCreated since it's automatically set for you by Grails if you use that name, so you only need to specify values for the 'real' properties of the class. It's not important to this issue though.
If you want the most recent item by created date, there are a few different ways you could do this but I think this makes the most sense:
def mostRecent = Burndown.listOrderByDateCreated(max: 1, order: 'desc')[0]
or if you retain your name
def mostRecent = Burndown.listOrderByCreateDate(max: 1, order: 'desc')[0]
This is described at http://grails.org/doc/latest/ - it's a fine manual, worthy of reading.

Not a Grails user, so below should be corrected accordingly by a Grails'ist
If domains are related, try something like:
Foo.findAllInList(Bar.list([group:'create_date']))

Related

MDX Calculated Member filter using attribute not working

I have this setup:
ID T Date
2 T2 2022-11-18
3 T1 2022-11-21
and in the main fact table there are deals with ID 2 and 3.
Date is an attribute and appears, and works correctly, as a slicer in a pivot table in Excel. T is also an attribute, not visible, purely for the calculated members.
I created a Calculated Member and it doesn't work:
([Date].[T].&[T2], [Measures].[Notional_SUM])
However a check/test using ID does:
([Date].[ID].&[2], [Measures].[Notional_SUM])
obviously this works as 2 is actually in the fact table but what have I forgotten such that using T does not work?
I want to be able to use T as there'll always be T1 and T2 dates but I may not always know the ID (auto- generated by the SQL script rolling the dates).
***EDIT - After testing in Excel I realised that the one I thought does not work actually does if Date is removed from the slicer/top setup.
So obviously the top/slicer is a WHERE on just that date meaning my calculated member
([Date].[T].&[T2], [Measures].[Notional_SUM])
does not 'find' any T2 in the data it sees.
So how can I have a Calculated Member that always shows the T2 data?
I'm constructing an SSAS copy of an existing in-memory Java OLAP cube which does this and I have to ensure all dims/measures are the same.
Thanks
Leigh
tilleytech.com
it has been long long time since I wrote MDX, and as I do not have a running SSAS to debug your issue, I will try to dig the answer from my memory.
There is a difference between the use of &, which I believe is to be used on keys, and not on members. Try to use this:
([Date].[T].[T2], [Measures].[Notional_SUM])
So actually as I've not used SSAS before I'm still learning bits and I had not checked out the attribute relationship tab.
I used the attribute relationship tab to define that T is related to Date and not ID (the ID links to the fact tables).
Once this was done the behaviour now works and when Date is changed the T2 values, and move/diff calculated members, all work as expected.

SQL Server 2012 Managment Studio Basic SELECT queries

I am new to SQL Server. I have been assigned to do some simple queries to start off, then eventually move on to more complex queries.
I have spent a lot of time on this website: http://www.w3schools.com and I understand it, I think, but then when I go back to my company's database, I find myself searching from many, many, different tables with different information.
For example, a table would say [Acct_Name] and the query comes back with not the correct account name (s) that I need. Any advice that you think might help me? Thank you.
It sounds like you are looking to limit your results to specific accounts. There are many ways to go about this, so no one will be able to give you a all encompassing answer but if you are looking to just pull a single account
SELECT * FROM (your table name) WHERE Acct_Name = 'the account name'
The * means you are selecting all columns in the table and your WHERE clause is where you set your search conditionals, like account name or by account ID. If you had a account creation date, you could get all accounts created on or before a date like this
SELECT * FROM (your table name) WHERE Created < '2016-06-01 00:00:00'
Replace the column name 'Created' with the column that holds the date field of account creation
Learning the WHERE clause and what you can do there to limit your results will get you on a solid footing to start, from there you will want to learn JOINs and how to link tables by primary keys.
Code academy has some great tutorials https://www.codecademy.com/learn/learn-sql

Jira: Status of all tickets at a certain point in time

I want to pull out month-by-month stats from a jira project, which shows the number of tickets that were in each state at the start of each month (similar to the Cummulative Flow Diagram, but extractable).
Is there a way in JQL or SQL to get the status of all tickets in a project at a specific point in time?
If you want to do this via SQL for one specific date, Atlassian provides instructions for related useful queries on JIRA 4.x. A particularly-relevant one would seem to be the "Find Statuses of all issues in a project on a given date" query, but it will be a bit of an uphill battle to do this over a varying date range.
These queries are still mostly relevant for more modern versions of JIRA, with the main concern being that the JI.pkey column will be blank in JIRA 6+. To get this data back, you first need to join with the project table with ON project.id=JI.project, and then synthesize the issue key yourself as P.pkey || '-' || JI.issuenum. You will also probably need to apply typecasts to some of the joins (at least on some databases) since a few joins are trying to relate integer-typed columns with text columns.
For reference, their JIRA 4.x query was the following:
SELECT JI.pkey, STEP.STEP_ID
FROM (SELECT STEP_ID, ENTRY_ID
FROM OS_CURRENTSTEP
WHERE OS_CURRENTSTEP.START_DATE < '<your date>'
UNION SELECT STEP_ID, ENTRY_ID
FROM OS_HISTORYSTEP
WHERE OS_HISTORYSTEP.START_DATE < '<your date>'
AND OS_HISTORYSTEP.FINISH_DATE > '<your date>' ) As STEP,
(SELECT changeitem.OLDVALUE AS VAL, changegroup.ISSUEID AS ISSID
FROM changegroup, changeitem
WHERE changeitem.FIELD = 'Workflow'
AND changeitem.GROUPID = changegroup.ID
UNION SELECT jiraissue.WORKFLOW_ID AS VAL, jiraissue.id as ISSID
FROM jiraissue) As VALID,
jiraissue as JI
WHERE STEP.ENTRY_ID = VALID.VAL
AND VALID.ISSID = JI.id
AND JI.project = <proj_id>;
If you are open to using a commercial add-on, Arsenale Dataplane can do exactly what you want in a few clicks using the Issue Values Snapshots by Date report. Disclaimer: I work for the company that makes this product.
With JQL you can only look for Issues not for States. About the specific point of time, you can only get information about the current status, unless you develop a complex script that takes in account the current situation and the changes made after the date you want to check (ChangeHistoryManager).
On the other hand, you can configure a Board with a pie chart (in example), where you set the Status field to be shown. Additionaly, you can create a Notification so that each first of month you get an email with this information.
Probably more interesting the scripting solution, but absolutely longer in time, and more complex.
Regards

Few questions about Grails' createCriteria

I read about createCriteria, and kind of interested on how these works, and its usability in providing values for dropdown box.
So say, i have a table in the database, Resource table, where i have defined the table in the domain class called Resource.groovy. Resource table has a total of 10 columns, where 5 of it are
Material Id
Material description
Resource
Resource Id
Product Code
So using the createCriteria, and i can use just like a query to return the items that i want to
def resList = Resource.createCriteria().list {
and {
eq('resource', resourceInstance)
ne('materialId', '-')
}
}
Where in the above, i want to get the data that matches the resource = resourceInstance, and none of the materialId is equal to '-'.
I want to use the returned data from createCriteria above on my form, where i want to use some of the column on my select dropdown. Below is the code i used for my select dropdown.
<g:select id="resourceId" name="resourceId"
from="${resList}"
disabled="${actionName != 'show' ? false : true}" />
How do i make it so that in a dropdown, it only shows the values taken from column Product Code? I believe the list created using createCriteria returns all 10 columns based on the createCriteria's specification. But i only want to use the Product Column values on my dropdown.
How do i customize the data if in one of the select dropdown in my form, i wanted to show the values as "Resource Id - Resource Description"? The values are combination of more than 1 columns for one select dropdown but i don't know how to combine both in a single select dropdown.
I read that hql and GORM query are better ways of fetching data from table than using createCriteria. Is this true?
Thanks
First of all refer to the document for using select in Grails. To answer all questions:
Yes, the list to select from in the dropdown can be customized. In this case it should be something like from="${resList*.productCode}"
Yes, this can be customized as well with something like
from="${resList.collect { \"${it.resourceId} - ${it.resourceDesc}\" } }"
It depends. If there are associations involved in a domain then using Criteria will lead to eager fetches which might not be required. But with HQL one gets the flexibility of tailoring the query as needed. With latest version of Grails those boundries are minimized a lot. Usage of DetachedCriteria, where queries etc are recommended whereever possible. So it is kind of mixing and matching to the scenario under consideration.

Selecting specific joined record from findAll() with a hasMany() include

(I tried posting this to the CFWheels Google Group (twice), but for some reason my message never appears. Is that list moderated?)
Here's my problem: I'm working on a social networking app in CF on Wheels, not too dissimilar from the one we're all familiar with in Chris Peters's awesome tutorials. In mine, though, I'm required to display the most recent status message in the user directory. I've got a User model with hasMany("statuses") and a Status model with belongsTo("user"). So here's the code I started with:
users = model("user").findAll(include="userprofile, statuses");
This of course returns one record for every status message in the statuses table. Massive overkill. So next I try:
users = model("user").findAll(include="userprofile, statuses", group="users.id");
Getting closer, but now we're getting the first status record for each user (the lowest status.id), when I want to select for the most recent status. I think in straight SQL I would use a subquery to reorder the statuses first, but that's not available to me in the Wheels ORM. So is there another clean way to achieve this, or will I have to drag a huge query result or object the statuses into my CFML and then filter them out while I loop?
You can grab the most recent status using a calculated property:
// models/User.cfc
function init() {
property(
name="mostRecentStatusMessage",
sql="SELECT message FROM statuses WHERE userid = users.id ORDER BY createdat DESC LIMIT 1,1"
);
}
Of course, the syntax of the SELECT statement will depend on your RDBMS, but that should get you started.
The downside is that you'll need to create a calculated property for each column that you need available in your query.
The other option is to create a method in your model and write custom SQL in <cfquery> tags. That way is perfectly valid as well.
I don't know your exact DB schema, but shouldn't your findAll() look more like something such as this:
statuses = model("status").findAll(include="userprofile(user)", where="userid = users.id");
That should get all statuses from a specific user...or is it that you need it for all users? I'm finding your question a little tricky to work out. What is it you're exactly trying to get returned?