I need some help in this.
I have a Table A (Master) and a Table B (Child).
I'm using DevExpress XAF.
I need to Evaluate last row in Child and show it to users in Master table A.
Lets say table A has the followind fields:
Oid,
Employee,
Address
[Name] = Persistent filed for Employee
Lets say Table B has the following fields:
Oid,
Employee (References the tbale A),
Status (Open, Assigned, Closed),
Status Date
The Child table has at least 2 records for each Master record:
Oid Employee Status Status Date
1 Mark Open 2015-12-12
2 Mark Assigned 2015-12-13
3 Mark Closed 2015-12-29
So far I used this:
[PersistentAlias("TableB[Status != 'Closed']")]
public GetStatus
{
get
{return EvaluateAlias(GetStatus)};
}
I want to show in Master Table A, for each Employee, the last Status of Child List.
When I run this code, I get Open, because it is different from Closed, but what I want is if last line in Table B is Status = Closed, is should return Closed.
Don't know if I explayned right!
Any ideas?
Thanks
You should use aggregate functions to pick the last element of a collection, for instance, max and single functions.
[PersistentAlias("TableB.Max(Date)")]
public DateTime? GetLastActionDate
{
get
{return (DateTime?)EvaluateAlias(GetLastActionDate)};
}
[PersistentAlias("TableB[Date == GetLastActionDate].Single()")]
public TableB GetStatus
{
get
{return (TableB)EvaluateAlias(GetStatus)};
}
Related
Please forgive my ignorance on sqlalchemy, up until this point I've been able to navigate the seas just fine. What I'm looking to do is this:
Return a count of how many items are in the table.
Return a count of many times different statuses appear in the table.
I'm currently using sqlalchemy, but even a pure sqlite solution would be beneficial in figuring out what I'm missing.
Here is how my table is configured:
class KbStatus(db.Model):
id = db.Column(db.Integer, primary_key=True)
status = db.Column(db.String, nullable=False)
It's a very basic table but I'm having a hard time getting back the data I'm looking for. I have this working with 2 separate queries, but I have to believe there is a way to do this all in one query.
Here are the separate queries I'm running:
total = len(cls.query.all())
status_count = cls.query.with_entities(KbStatus.status, func.count(KbStatus.id).label("total")).group_by(KbStatus.status).all()
From here I'm converting it to a dict and combining it to make the output look like so:
{
"data": {
"status_count": {
"Assigned": 1,
"In Progress": 1,
"Peer Review": 1,
"Ready to Publish": 1,
"Unassigned": 4
},
"total_requests": 8
}
}
Any help is greatly appreciated.
I don't know about sqlalchemy, but it's possible to generate the results you want in a single query with pure sqlite using the JSON1 extension:
Given the following table and data:
CREATE TABLE data(id INTEGER PRIMARY KEY, status TEXT);
INSERT INTO data(status) VALUES ('Assigned'),('In Progress'),('Peer Review'),('Ready to Publish')
,('Unassigned'),('Unassigned'),('Unassigned'),('Unassigned');
CREATE INDEX data_idx_status ON data(status);
this query
WITH individuals AS (SELECT status, count(status) AS total FROM data GROUP BY status)
SELECT json_object('data'
, json_object('status_count'
, json_group_object(status, total)
, 'total_requests'
, (SELECT sum(total) FROM individuals)))
FROM individuals;
will return one row holding (After running through a JSON pretty printer; the actual string is more compact):
{
"data": {
"status_count": {
"Assigned": 1,
"In Progress": 1,
"Peer Review": 1,
"Ready to Publish": 1,
"Unassigned": 4
},
"total_requests": 8
}
}
If the sqlite instance you're using wasn't built with support for JSON1:
SELECT status, count(status) AS total FROM data GROUP BY status;
will give
status total
-------------------- ----------
Assigned 1
In Progress 1
Peer Review 1
Ready to Publish 1
Unassigned 4
which you can iterate through in python, inserting each row into your dict and adding up all total values in another variable as you go to get the total_requests value at the end. No need for another query just to calculate that number; do it manually. I bet it's really easy to do the same thing with your existing second sqlachemy query.
I have a Report which i want to check on if a certain field on the SalesLine table is filled, if so, show the value of this field.
I have 2 custom tables which the report is using.
Table A & Table B
Table A, has a method with the following query:
select firstonly Id from TableB
where TableB.Id == this.Id;
return TableB.Id;
Table B, has a method with the following code:
public SalesLine salesLine()
{
return SalesLine::findInventTransId(this.InventTransId);
}
Now I need to check on the report, throughout these 2 methods, if Field X on the Sales Line table is filled. How can I accomplish this?
Modify table A method as below.
select firstonly Id,InventTransId from TableB where TableB.Id == this.Id;
return TableB.salesLine().Fieldx ? TableB.Id : 0 ;
The answer to your question seems to obvious to me...so maybe you're not asking your question correctly:
if(TableB.salesLine().FieldX)
info("FieldX is filled");
I have a reservation table which the user will insert records into.
The User does not select the car just the type.
Once the record is inserted I want some triggers to do the following:-
The date and vehicle combination to a log file the data and vehicle are UNIQUE(date,car) so the same reservation cannot be made twice therefore a car cannot be double booked.
SO my issue is how do I now get the trigger to select the next available car of that type?
I can get it to select the next car by just saying Car.carid != Log.carid but that is not using the date as a second check so I could not then use the vehicle on another date.
Simply putting AND between the check doesnt work meaning
WHERE Car.carid != Log.carid AND Reservation.date != C.datewhen
Some guidance would be much appreciated!
I think this query is what you are after...
SELECT MIN(c.carid)
FROM all_cars c
WHERE c.type = 'CAR TYPE'
AND NOT EXISTS
(SELECT 1
FROM reservation r
WHERE r.date = 'THE DATE'
AND r.carid = c.carid)
If the query returns a NULL value then no cars are available.
Or you could take off the MIN and just use the first record returned.
I have 3 tables tblpermission, tblgroup, tblassigngrouppermission. Then I have a design there have two comboboxes for selecting group and permission. After select I add it to a listview. Then I save it, at that time it will go to the table tblassigngrouppermission.
That table has columns such as assign id (default increment), groupid, permission id. All are correctly added to the table. After that saving if I select the same group for assign permission. Then I select already assigned permission and click save it added to the table. But I need there not add the already assigned permission to the table.
How can I do this?
When you are saving the data back to tblassigngrouppermission you will have to check the presence of group_id and permission_id in the table.
if they are present you will have to update tblassigngrouppermission else you will have to insert in tblassigngrouppermission
If you are using stored procedure you could do this
IF NOT EXISTS(Select permissionId From tblassigngrouppermission
Where groupId=#GroupID AND permissionId=#permissionId)
Begin
INSERT INTO tblassigngrouppermission(groupId,permissionId) Values(#groupId, #PermissionID)
End
You can also check from your code
==> Write a function that test if the permission already exist
bool GroupPermissionExists(int groupId, int permissionId)
{
//Select Where GroupId=groupId AND PermissionID=permissionId
}
if(!GroupPermissionExists(10, 123))
{
AddPermissionToGroup(10, 123);
}
I am using vb. I have an aspx page that contains a TextBox (txtStudentName), a DropBox (dropdownlistGroupName) and a save button.
student table
StudentID StudentName GroupID
1 ABC 1
2 DEF 1
3 GHI 2
Group table
GroupID GroupName
1 Pear
2 Apple
3 Strawberry
When I click on the Save button it will insert in student, saying that this student belongs to this group name.
But at the save button, how am I going to check / validate that this group name, for example Apple, will only have 20 students belong to the group. If the user clicks on saving the 21st student, it should display a message saying that the group is full.
I am not sure how to check with the database.
Hope someone can tell me what I should do, along with an example that is nice and easy for me understand.
In your click event for the button, do a count from STUDENT for the GroupID that will be inserted. If the count is > 19, display error, if the count is < 20, insert the record.
You could also not allow a given GroupID to be available for selection if there is already 20 or more records in STUDENT. If you have GroupIDs populating a combo box for example, you could alter the criteria for populating the combo box to only include GroupID having count < 20.
I would still check the count in STUDENT prior to insert even if I was only displaying GroupIDs with less than 20 records (at the time the combo box was populated), just in case a record is inserted by someone else after your combo box populated.
I would use the following determine the number of students in the group prior to inserting a new row in the student table:
int count;
using (SqlConnection connection = new SqlConnection())
{
using (SqlCommand command = new SqlCommand("SELECT COUNT(*) FROM [Student] WHERE [GroupID] = #GroupID", connection))
{
command.Parameters.AddWithValue("#GroupID", groupId);
connection.Open();
count = (int)command.ExecuteScalar();
}
}
if (count > 20)
{
// Display error message.
}
else
{
// Insert row into Student table
}
Alternatively, you could insert the row into the Student table, then do a count and if the count is > 20 rollback the transaction and display a message.