SOQL Query not bringing back parent with no comments - soap

Due to the way this is structured I can't bring back groups with no comments/feeds in them, unfortunately trying to invert this brings up multiple errors as CollaborationGroup does not understand the relationship it has with CollaborationGroupFeed.
Here is the query:
SELECT
c.Parent.Id,
c.Parent.OwnerId,
c.Parent.CreatedById,
c.Id,
c.ParentId,
(
SELECT
Id,
FeedItemId,
ParentId
FROM FeedComments
)
FROM CollaborationGroupFeed c
I can't do it like this though for whatever reason:
SELECT
Id,
OwnerId,
CreatedById,
(
SELECT
Id,
ParentId
FROM CollaborationGroupFeeds
),
(
SELECT
Id,
FeedItemId,
ParentId
FROM FeedComments
)
FROM CollaborationGroup
Didn't understand relationship 'CollaborationGroupFeed' in FROM part of query call.`
EDIT
So lets say I have a Group that I just created called Foo
[FOO]
Foo has one Post in it BlahPost
[FOO]
|
|_BlahPost
Lets say BlahPost has a comment (or several)
[FOO]
|
|_BlahPost
|_Comment 1
|_Comment 2
The query above will return all of this.
Now lets say I have a new Group Bar
[Bar]
Since there are NO posts/comments the query above returns nothing since I'm working from child to parent,
and parent has no posts. I am looking for a query that starts at the parent CollaborationGroup and moves
down to CollaborationFeed which will display FeedComment
Make more sense? The order is mess up, I'm working from the middle and should be working from the top

Try using Chatter in Apex, which is Chatter REST API resource actions exposed as static methods in the Apex ConnectApi namespace. It's a much easier way to access Chatter data.
http://www.salesforce.com/us/developer/docs/apexcode/Content/connectAPI_overview.htm
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_connect_api.htm

Related

Retrieving inactive employees

I have the following query using the Invantive Query Tool connecting to NMBRS.
select e.number
, es.EmployeeId
, e.displayname
, es.ParttimePercentage
, es.startdate
from Nmbrs.Employees.EmployeeSchedules es
left
outer
join Nmbrs.Employees.Employees e
on es.EmployeeId = e.id
order
by e.displayname
, es.startdate
(I want to retrieve all mutations in part-time percentage/schedule)
However Nmbrs.Employees.Employees only shows active employees. And I need that because that shows the employee ID as shown in Nmbrs.Employees.EmployeeSchedules is not the employee ID shown in the UI rather it is an internal ID.
I did notice Nmbrs.Employees.Employees has an additional where clause (as per documentation):
Additional Where Clause:
- CompanyId
- active
The following query
select * from Nmbrs.Employees.Employees where active = 1
gives an error:
Unknown identifier 'active'.
Consider one of the following: Nmbrs.Employees.Employees.PartitionID, Nmbrs.Employees.Employees.Id, Nmbrs.Employees.Employees.Number, Nmbrs.Employees.Employees.DisplayName, Employees.Employees.PartitionID, Employees.PartitionID, PartitionID, Employees.Employees.Id.
Active isn't mentioned so I don't know if that is usable.
active is a server-side filter on Nmbrs.nl. It defaults to the value "active". Don't ask me why they choose to have an API reflect the user interface; it is weird, but it is the way it is.
To retrieve all employees from one or more companies (partitions), use:
use all
select * from employeesall
OR
select * from employeesinactive
These are recent additions to the Nmbrs.nl API tables supported.
Note that the output does NOT contain whether an employee is active. When you need that too, please use a view or:
select 'active' type
, t.*
from nmbrs..employeesactive t
union all
select 'inactive' type
, t.*
from nmbrs..employeesinactive t

Filter and display database audit / changelog (activity stream)

I'm developing an application with SQLAlchemy and PostgreSQL. Users of the system modify data in 8 or so tables. Consider this contrived example schema:
I want to add visible logging to the system to record what has changed, but not necessarily how it has changed. For example: "User A modified product Foo", "User A added user B" or "User C purchased product Bar". So basically I want to store:
Who made the change
A message describing the change
Enough information to reference the object that changed, e.g. the product_id and customer_id when an order is placed, so the user can click through to that entity
I want to show each user a list of recent and relevant changes when they log in to the application (a bit like the main timeline in Facebook etc). And I want to store subscriptions, so that users can subscribe to changes, e.g. "tell me when product X is modified", or "tell me when any products in store S are modified".
I have seen the audit trigger recipe, but I'm not sure it's what I want. That audit trigger might do a good job of recording changes, but how can I quickly filter it to show recent, relevant changes to the user? Options that I'm considering:
Have one column per ID type in the log and subscription tables, with an index on each column
Use full text search, combining the ID types as a tsvector
Use an hstore or json column for the IDs, and index the contents somehow
Store references as URIs (strings) without an index, and walk over the logs in reverse date order, using application logic to filter by URI
Any insights appreciated :)
Edit It seems what I'm talking about it an activity stream. The suggestion in this answer to filter by time first is sounding pretty good.
Since the objects all use uuid for the id field, I think I'll create the activity table like this:
Have a generic reference to the target object, with a uuid column with no foreign key, and an enum column specifying the type of object it refers to.
Have an array column that stores generic uuids (maybe as text[]) of the target object and its parents (e.g. parent categories, store and organisation), and search the array for marching subscriptions. That way a subscription for a parent category can match a child in one step (denormalised).
Put a btree index on the date column, and (maybe) a GIN index on the array UUID column.
I'll probably filter by time first to reduce the amount of searching required. Later, if needed, I'll look at using GIN to index the array column (this partially answers my question "Is there a trick for indexing an hstore in a flexible way?")
Update this is working well. The SQL to fetch a timeline looks something like this:
SELECT *
FROM (
SELECT DISTINCT ON (activity.created, activity.id)
*
FROM activity
LEFT OUTER JOIN unnest(activity.object_ref) WITH ORDINALITY AS act_ref
ON true
LEFT OUTER JOIN subscription
ON subscription.object_id = act_ref.act_ref
WHERE activity.created BETWEEN :lower_date AND :upper_date
AND subscription.user_id = :user_id
ORDER BY activity.created DESC,
activity.id,
act_ref.ordinality DESC
) AS sub
WHERE sub.subscribed = true;
Joining with unnest(...) WITH ORDINALITY, ordering by ordinality, and selecting distinct on the activity ID filters out activities that have been unsubscribed from at a deeper level. If you don't need to do that, then you could avoid the unnest and just use the array containment #> operator, and no subquery:
SELECT *
FROM activity
JOIN subscription ON activity.object_ref #> subscription.object_id
WHERE subscription.user_id = :user_id
AND activity.created BETWEEN :lower_date AND :upper_date
ORDER BY activity.created DESC;
You could also join with the other object tables to get the object titles - but instead, I decided to add a title column to the activity table. This is denormalised, but it doesn't require a complex join with many tables, and it tolerates objects being deleted (which might be the action that triggered the activity logging).

How to group by linked verticies

I am attempting to build a family tree database with OrientDB (v2.0.2 if it makes a difference). I have a vertex called 'Person' and an edge called 'Child' (so the edge goes out of the parent and in to the child).
For some example data, lets say 'Jane' has had 2 children with 2 different partners (so 4 in total). With Janes rid, I would like to get a list of all her children grouped by their other parent. So the result set I want should be something like
with Bob with Joe
-------- --------
Alpha Gamma
Beta Delta
I can get the children with a simple query select expand( out('Child') ) from #12:6, but I am stumped with what to do from this point. Also note that in some cases, the other parent may not be known, and should thus be listed in an additional group with 'unknown' parent.
I am using the database via pyorient (python), so I could always loop over the results and manually add them to groups in a dict, but this doesn't sound like the proper solution.
Edit: after much trial and error, I have come up with
select unionall($current) as children, $parents as parents from ( select expand(out('Child')) from #12:6 ) let $parents = (select expand(in('Child')) from $current) group by $parents
This gives me a raw result along the lines of
"children": ["#12:0","#12:5"],
"parents": ["#12:1","#12:6"],
Is this as good as it gets? What is the best way to get all these records via the rids, so I can have all the persons info (name, etc)?
From what you mentioned, I am assuming that you have two vertices called Person and Child.
In that case, what you can do is maintain another edge called Partners or something like that.
Now create an edge from Person to itself. This will help in maintaining record of Partners.
Also, have a Children edge that keeps links from the Person to Child vertices. It is always recommended not to use the default E.
To retrieve the child of a person called 'John' with all his partners, you can do:
select expand( $f ) let
$a = (select expand(out()) from
(select expand(out('Partners')) from Person where personName='John')),
$b = (select expand(out('Children')) from Person where personName='John'),
$f = UNIONALL( $a, $b )

How does a self join table decide what to display when conditions are "identical"

I have a simple chat table. The chat table has a user_id column and a recipient_id column and a boolean agrees_to_chat column.
What I'd like to do, is display the users for which user 1 wants to chat with and whom all other users also want to chat with user 1.
(Note that there will be cases where 1 agrees to chat with 2, but 2 has not gone online to signal a preference yet. Obviously in those cases I don't want a chat to show up.)
Here's what I've come up with so far.
SELECT c1.user_id, c1.recipient_id, c2.user_id, c2.recipient_id FROM chats c1, chats c2
WHERE c1.recipient_id = c2.user_id
AND c1.user_id = c2.recipient_id
AND c2.user_id=1
AND c2.agrees_to_chat=true
AND c1.agrees_to_chat=true
For some reason setting c2.user_id = 1 results in what I want: records where user_id = 1, along with people who have agreed to chat listed in the recipient_id column.
However if I set it to c1.user_id=1 I get the same results flipped over. Namely, now my results are still people who have agreed to chat, but now the recipient_id = 1 for all results, and the user_id is the different users.
This matters to me because if I want to serve data that shows everyone whose agreed to chat with user 1. But if I decide to reference recipient_id in my code, I need to know that won't change...For example, on my computer I noticed that c2.user_id =1 results in what I want, but in this sql fiddle it seems to be that c1.user_id=1 gets what I need... http://sqlfiddle.com/#!15/799a9/2
So what's going on here? Is there something I'm not understanding about my query? Alternatively is there a better query for what I'm trying to achieve?
You don't need all 4 columns, since you already know 1st and 4th (and 2nd and 3rd) will be equal. Use SELECT c2.user_id, c2.recipient_id FROM ... or SELECT c1.user_id, c1.recipient_id FROM .... In case you actually need several copies of the same column from the self-joined tables, you can give names to them: SELECT c1.user_id AS user_id1, c1.recipient_id AS recipient_id1, c2.user_id AS user_id2, c2.recipient_id AS recipient_id2 FROM ...

How to remove duplicate records in OpenERP ver 6.1.1

I want to get Employee ID, Leave Reason, Leave type and Employee name for my internal report purpose. I wrote a SQL query to retrieve those data and I got some duplicates also.
Seems it's missing some join / foreign id mapping part missing
select
h.id as employee_id,h.name as leave_reason,
s.name,r.name as res_name
from
hr_holidays_status s,
hr_holidays h,
hr_employee e,
resource_resource r
where
h.employee_id=e.id and
h.holiday_status_id=s.id and
e.resource_id=r.id
order by
resource_id
Your query looks correct, but maybe you're getting unexpected results because the hr_holidays table contains both "Leave Requests" and "Leave Allocations". It's like a double-entry system where leave allocations increase the quantity of leave days available for an employee or an employee category, while leave requests decrease it.
Your query should probably take this distinction into account, and you might also want to filter on other fields like the state, because some of the records may not be validated yet.
Looking at the declaration of the hr.holidays model in 6.1, you will see a few noteworthy fields that could be used in your query:
type: can be Allocation ('add') to represent an increment, or Request ('remove') to represent a decrement
holiday_type: can be Employee ('employee'), in which case the employee_id column indicates which employee, or Category ('category'), in which case the category_id column indicates which category
state: New ('draft'), Waiting Approval ('confirm'), Refused ('refuse'), Waiting Second Approval ('validate1'), Approved ('validate'), Cancelled ('cancel')