Getting Parent Table entries comparing Child fields.
Hi all,
I have a parent table and a child table. I need the parent table entry comparing on the child table.
Here goes my scenario:
ReqHeader:
ReqID
CreatedOn
Text
ReqItem:
ReqID
Date
Status
Now I want all the entries from ReqHeader with only those 3 columns where ReqItem.Date is between two dates and ReqItem.Status equal a Status. I have two SQL queries for illustration using join and query inside a query:
- select h.ReqID, h.ClientID, h.CreatedOn, h.Text From reqheader as h join reqitem as i on h.ReqID = i.ReqID where
i.date between '20090501' and '20090607' and Status = 2; - select * from reqheader where ReqID in (select ReqID from reqitem where date between '20090501' and '20090607' and Status = 2);
Both of them give the same result. As shown I only need columns from the header table with no repetition.
I have done simple qcubed queries involving single table but not multiple. I am confused on how to implement it in Qcubed using QQ queries or otherwise.
Please help me implement most optimized solution out of the three. Later I would be displaying the results in a datagrid on the dialog panel.
Thanks.

Is there an actual Req table which relates to these IDs? What are the SQL relationships between the two ReqID columns?
In theory, you should be able to do something like:
<?php$headers = ReqHeader::QueryArray(
QQ::AndCondition(
QQ::Between(QQN::ReqHeader()->Req->ReqItems->Date, '2009-05-01', '2009-06-07'),
QQ::Between(QQN::ReqHeader()->Req->ReqItems->Status, 2)
)
);
?>
Thank you Vexed Panda.
The relationship the tables share is only through ReqID and there is no other table. ReqID is primary key for ReqHeader table and ReqItem has ReqID and Item as primary key. In my relationship.txt file I have defined:
ReqItem.ReqID => ReqHeader.ReqID
I tried QQN::ReqHeader()->ReqItems->Date but I got the error: "Undefined GET property or variable in 'QQNodeReqheader' class: ReqItems". Please help.
Thanks.
If you generated your code, did it show you that one of those tables has any relationships? It seems that qcubed doesn't know about your relationship.
I got the message that ReqItem is created with relationships.
First, you probably don't have property name in plural form. Instead of "ReqHeader()->ReqItems" you probably have "ReqHeader()->ReqItem".
You can look up the class "QQNodeReqheader" and see, which properties does it have (in __get method). It should be located in file "includes/data_classes/generated/ReqheaderGen.class.php" or similar.
I changed the name to singular yet same message. I have attached my ReqHeaderGen.class.php here: http://pastebin.com/m4d867f6b
Not sure why its not working. Please help. Thanks.
It looks like the name is actually ReqitemAsReqid, so in my example code, you should be able to replace Req->ReqItems with ReqitemAsReqid.
Thanks a lot Vexed Panda, it worked.
But the name gives me jitters. As your filtered data grid also doesn't work in my qcubed implementation. Do you think there might be something screwed up with my Qcubed?
No, I'd say your code looks pretty normal. The shared primary key approach is unusual, causing the unusual name for the relationship, but functionally it should work great.
I'll try and find more time to look into your issues with QFilteredDataGrid, since it really should be working from what I've seen.
Thank you.
Two more things regarding querires:
<?phpreturn array_unique(ReqHeader::QueryArray(
QQ::AndCondition(QQ::Equal(QQN::Reqheader()->ClientID, $clientID),
QQ::GreaterOrEqual(QQN::ReqHeader()->ReqitemAsReqid->Date, $dttStartDate),
QQ::LessOrEqual(QQN::Reqheader()->ReqitemAsReqid->Date, $dttEndDate),
QQ::Like(QQN::Reqheader()->ReqitemAsReqid->Status, $numStatus))
));
?>
Currently I am happy with the query as it works. But using OO db seems more fun.
meetsang,
When I troubleshoot my own QQuery stuff, I find it useful to see what SQL expressions QQuery is generating - this helps me understand where I screwed up (and it's usually my fault, not QQuery's :-)).
I'd recommend you to do the same for both of your questions, and analyze the SQL yourself - if you need help, do post it here.
If you want to get distinct records you can include in the clause:
return ReqHeader::QueryArray(QQ::AndCondition(QQ::Equal(QQN::Reqheader()->ClientID, $clientID),
QQ::GreaterOrEqual(QQN::ReqHeader()->ReqitemAsReqid->Date, $dttStartDate),
QQ::LessOrEqual(QQN::Reqheader()->ReqitemAsReqid->Date, $dttEndDate),
QQ::Like(QQN::Reqheader()->ReqitemAsReqid->Status, $numStatus)),
QQ::Clause(QQ::Distinct())
)
If you want to get more precise distinct eg SELECT DISTINCT regheader.client_id from regheader, I think you must use custom Query.
Thank you revvi, that worked.
Alex, thank you for the tip, I am reading Qcubed code sometimes. I know it helps a lot.
I use between with dates with no issues. Whats worth pointing out though is that if you're comparing dates, "2009-01-01" < "2009-01-01 12:01am". So if you meant to cover the entirety of "2009-01-01", you should probably be using 2009-01-02 - 1 millisecond instead.
I just tried using QQ::Between on QDateTimes, and it does not work.
$beforeDate = QDateTime::Now();
$beforeDate->AddDays(-30);
$afterDate = QDateTime::Now();
$afterDate->AddDays(-29);
$employers = Employer::QueryArray(
QQ::Between(QQN::Employer()->RegistrationDate,
$beforeDate,
$afterDate)
);
I get the following error: Unable to cast QDateTime object to string
This is because the QQConditionBetween constructor tries to cast the operands into strings, and that fails. The following does work, though:
$employers = Employer::QueryArray(QQ::Between(QQN::Employer()->RegistrationDate,
$beforeDate->__toString('YYYY-MM-DD'),
$afterDate->__toString('YYYY-MM-DD')));
We should fix this to allow dates to work explicitly, without these tricks.
Thanx Alex above code helps me a lot..
once again thanx a lot
Revvi,
You're exactly right! Apparently there is no option but to use an ad-hoc SQL query for statements like this: SELECT DISTINCT table.field from table;
I've been trying to populate a QListbox with the distinct database FIELD results - which seems to me like it would be a very common task when developing a web 2.0 system (especially in regards to creating a dynamic Select Input).
Obviously everyone is going to automatically expect that functionality from a feature called QQ::Distinct -- maybe I just expect too much.
To see the reasoning behind this omission in the original framework - take a look here: http://www.qcodo.com/forums/forum.php/2/1669
And then to not even mention it in the Examples documentation!
I mean don't get me wrong, Mike's response makes total sense from a logical programming standpoint - but from an expectation of the code's response perspective (for the average programmer), it is a complete FAIL.
Are there more curve-balls like this that I should be expecting as I learn to work with Qcubed?
The underlying reason behind this lack of support for field-level SELECT DISTINCT is that QCubed does not allow you to pick and choose e database columns you want as a result of your QQuery. This, of course, means that every single field is selected with every query, and select distinct only gets you wholesale distinct records, which is not what you want.
We do want to add support for column selection into QQuery, but its quite a complex undertaking. You can see a related discussion in this thread: http://qcu.be/content/memory-limit-error This thread also has a few great links in there, do review them if you are deeplyinterested in this subject.
You're right that we should probably write an example article on this subject. Would you be up for doing it, mcluver? This would really help the community.