Multiple Inner Joins CAML query - sql

I'm trying to convert the following SQL statement to a CAML query:
SELECT t.Id, t.Name, t.CustomerId
FROM Ticket AS t
INNER JOIN
Customer AS c1 ON t.CustomerEMail = c1.EMail
INNER JOIN
Customer AS c2 ON c1.CompanyNo = c2.CompanyNo
WHERE (c2.Email = 'client1#co1.com')
Using CAMLJS, I got this far: (CompanyNo is equivalent to Nav_CustomerNo)
var query = new CamlBuilder()
.View(["Title", ...])
.InnerJoin("ClientLookup", "c1")
.Select("EMail", "c1Email")
.InnerJoin("ClientLookup", "c2")
.Select("Nav_CustomerNo", "c2CompanyNo")
.Query()
.Where()
.All()
.ToString()
But I'm not sure how to proceed from here. How do I convert the
Customer AS c1 ON t.CustomerEMail = c1.EMail
line? I am thinking something like:
.Where("c1Email").EqualTo(??
Here is the equivalent CAML:
<View>
<ViewFields>
<FieldRef Name="Title" />
<FieldRef Name="Ticket_MainBody" />
<FieldRef Name="Ticket_SupportID" />
<FieldRef Name="ClientLookup" />
<FieldRef Name="IsPrivateTicket" />
<FieldRef Name="Ticket_IsFAQ" />
</ViewFields>
<Joins>
<Join Type="INNER" ListAlias="c1">
<Eq>
<FieldRef Name="ClientLookup" RefType="ID" />
<FieldRef Name="ID" List="c1" />
</Eq>
</Join>
<Join Type="INNER" ListAlias="c2">
<Eq>
<FieldRef Name="ClientLookup" RefType="ID" />
<FieldRef Name="ID" List="c2" />
</Eq>
</Join>
</Joins>
<ProjectedFields>
<Field ShowField="EMail" Type="Lookup" Name="c1Email" List="c1" />
<Field ShowField="Nav_CustomerNo" Type="Lookup" Name="c2CompanyNo" List="c2" />
</ProjectedFields>
<Query>
<Where />
</Query>
</View>

Just spent a considerable time this morning trying to work this out and I think I have a solution for you.
First - let's start with some generic pseudo structure:
ParentTable: Id, Title, ChildTableReference
ChildTable: Id, Title, BabyTableReference
BabyTable: Id, Title
So, we have a parent table that contains a reference. The table tied to that reference contains a reference to another table under that.
Here is a simple practical example:
(parent) CustomerOrder: Id, Title, CustomerID
(child) Customer: Id, Title, RegionID
(baby) Region: Id, Title
So, what if we wanted the following query response:
CustomerOrder_Id, CustomerOrder_Title, Customer_Title, Region_Title
The first part of the XML is easy:
<ViewFields>
<FieldRef Name='ID' />
<FieldRef Name='Title' />
<FieldRef Name='Customer_Title' />
<FieldRef Name='Region_Title' />
</ViewFields>
But how do we stitch together the tables? We use joins.
The first Join is very simple:
<Join Type='INNER' ListAlias='Customers'>
<Eq>
<FieldRef Name='CustomerID' RefType='ID' />
<FieldRef List='Customer' Name='ID' />
</Eq>
</Join>
This first join is ok and if all we wanted to do was view the customer name we would just have to add our Projection and we would be good to go. But, we also want the Region of this customer. For this, we need a second join. The trick to the second join is to add a list reference to the FIRST FieldRef statement. The exact line is: FieldRef List='Customers' Name='RegionID' RefType='ID' . Notice that the List= attribute points to the alias of the Child reference. Put another way, there is a reference list called Customers that contains a column called RegionID that is a reftype of ID. That needs to be equal to our new aliased table called Regions based on the root table Region on the ID attribute.
<Join Type='INNER' ListAlias='Regions'>
<Eq>
<FieldRef List='Customers' Name='RegionID' RefType='ID' />
<FieldRef List='Regions' Name='ID' />
</Eq>
</Join>
We are almost home now. At this point we need to create Projected Fields to spit out the Region.Title and Customer.Title attributes.
<ProjectedFields>
<Field ShowField='Title' Type='Lookup' Name='Customer_Title' List='Customers' />
<Field ShowField='Title' Type='Lookup' Name='Region_Title' List='Regions' />
</ProjectedFields>
Putting it all together then, your CAML query would be:
//Completed query
<View>
<ViewFields>
<FieldRef Name='ID' />
<FieldRef Name='Title' />
<FieldRef Name='Customer_Title' />
<FieldRef Name='Region_Title' />
</ViewFields>
<Joins>
<Join Type='INNER' ListAlias='Customers'>
<Eq>
<FieldRef Name='CustomerID' RefType='ID' />
<FieldRef List='Customer' Name='ID' />
</Eq>
</Join>
<Join Type='INNER' ListAlias='Regions'>
<Eq>
<FieldRef List='Customers' Name='RegionID' RefType='ID' />
<FieldRef List='Regions' Name='ID' />
</Eq>
</Join>
</Joins>
<ProjectedFields>
<Field ShowField='Title' Type='Lookup' Name='Customer_Title' List='Customers' />
<Field ShowField='Title' Type='Lookup' Name='Region_Title' List='Regions' />
</ProjectedFields>
<Query />
</View>
That should get you all the way there. Also - you can query (Where clause for instance) on any element you've joined to provided the field type is supported (text, refid, number, etc). Just remember that if you are going to query on say, the ID of the Region you will need to add the ID to your ProjectedFields.
// completed query with WHERE clause filtering by BABY table ID.
<View>
<ViewFields>
<FieldRef Name='ID' />
<FieldRef Name='Title' />
<FieldRef Name='Customer_Title' />
<FieldRef Name='Region_Title' />
</ViewFields>
<Joins>
<Join Type='INNER' ListAlias='Customers'>
<Eq>
<FieldRef Name='CustomerID' RefType='ID' />
<FieldRef List='Customer' Name='ID' />
</Eq>
</Join>
<Join Type='INNER' ListAlias='Regions'>
<Eq>
<FieldRef List='Customers' Name='RegionID' RefType='ID' />
<FieldRef List='Regions' Name='ID' />
</Eq>
</Join>
</Joins>
<ProjectedFields>
<Field ShowField='Title' Type='Lookup' Name='Customer_Title' List='Customers' />
<Field ShowField='ID' Type='Lookup' Name='Region_ID' List='Regions' />
<Field ShowField='Title' Type='Lookup' Name='Region_Title' List='Regions' />
</ProjectedFields>
<Query>
<Where>
<Eq>
<FieldRef Name='Region_ID' LookupId='True' />
<Value Type='Integer'>1</Value>
</Eq>
</Where>
</Query>
</View>

Related

CAML Query with IN + AND or other

My question is about caml query SP2010,
i've got colums as follow: Country, Role, Species, Species, Topic, Documenttype, Searchtext.
There is possible that user will search by Countries (multiple->UK,France,Belgium) and type document name like Doc_num_one.txt and add other criteria like Role, Species, Species, Topic, Documenttype. I've tried different queries but I think I stucked.
Below what I tried so far:
<Query>
<Where>
<In>
<FieldRef Name="Country"/>
<Values>
<Value Type="Lookup">United Kingdom</Value>
<Value Type="Lookup">Poland</Value>
<Value Type="Lookup">Belgium</Value>
</Values>
</In>
</Where>
</Query>
or
<Query>
<Where>
<And>
<Eq>
<FieldRef Name="Title" />
<Value Type="Text">doc num two</Value>
</Eq>
<Or>
<And>
<Eq>
<FieldRef Name="Country" />
<Value Type="Lookup">United Kingdom</Value>
</Eq>
<Eq>
<FieldRef Name="Role" />
<Value Type="Lookup">Super Admin</Value>
</Eq>
</And>
<And>
<Eq>
<FieldRef Name="Country" />
<Value Type="Lookup">Belgium</Value>
</Eq>
<Eq>
<FieldRef Name="Role" />
<Value Type="Lookup">Super Admin</Value>
</Eq>
</And>
<And>
<Eq>
<FieldRef Name="Country" />
<Value Type="Lookup">Poland</Value>
</Eq>
<Eq>
<FieldRef Name="Role" />
<Value Type="Lookup">Super Admin</Value>
</Eq>
</And>
</Or>
</And>
</Where>
</Query>
Solution:
<Query>
<Where>
<And>
<In>
<FieldRef Name="Country"/>
<Values>
<Value Type="Lookup">United Kingdom</Value>
<Value Type="Lookup">Poland</Value>
<Value Type="Lookup">Belgium</Value>
</Values>
</In>
<In>
<FieldRef Name="Role"/>
<Values>
<Value Type="Lookup">Super Admin</Value>
<Value Type="Lookup">Admin</Value>
<Value Type="Lookup">User</Value>
</Values>
</In>
</And>
</Where>
</Query>
The second query does not work because it has more than two child elements within the <Or> element. If you want to test more sub-conditions, you have to introduce helper elements:
<Or>
<And>...</And>
<And>...</And>
<And>...</And>
<And>...</And>
<And>...</And>
</Or>
becomes
<Or>
<And>...</And>
<Or>
<And>...</And>
<Or>
<And>...</And>
<Or>
<And>...</And>
<And>...</And>
</Or>
</Or>
</Or>
</Or>
The same applies to <And> elements.

Alex the CAML Query has "NO RESULTS"

My SharePoint 2010 CAML Query is not returning the expected results. It is returning nothing. What am I doing wrong?
<View>
<Query>
<Where>
<In>
<FieldRef ID="1d8376f2-5ac6-407f-9652-a74405a87846" Name="Bank_x0020_Choice" />
<Values>
<Value Type="Choice">Retail</Value>
<Value Type="Choice">Commercial</Value>
</Values>
</In>
</Where>
</Query>
<ViewFields>
<FieldRef ID="1d22ea11-1e32-424e-89ab-9fedbadb6ce1" Name="ID" />
<FieldRef ID="fa564e0f-0c70-4ab9-b863-0177e6ddd247" Name="Title" />
<FieldRef ID="1d8376f2-5ac6-407f-9652-a74405a87846" Name="Bank_x0020_Choice" />
<FieldRef ID="224ba411-da77-4050-b0eb-62d422f13d3e" Name="LinkFilename2" />
</ViewFields>
<RowLimit Paged="TRUE">1000</RowLimit>
</View>
Try to use the tool CAML Builder. With this tool you can check your CAML queries with no pre-configuration and no coding. There you can test your query, maybe there is simply an spelling error in your fieldrefs, values or names.

filtering in sharepoint caml

Below I have the view which i have in the list schema.The issue is that it never picks the where clause.It displays the order by clause correctly when I go to modify the view but not the where clause which should show up in the filter section.I also tried ceating a view in UI and then through sharepoint manager got the schema and then created a view but still does not work.Am I doing something wrong here.
<View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="Tab 1" DefaultView="FALSE" MobileView="TRUE" MobileDefaultView="FALSE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="T1.aspx">
<Toolbar Type="Standard" />
<XslLink Default="TRUE">main.xsl</XslLink>
<RowLimit Paged="TRUE">30</RowLimit>
<Query>
<OrderBy Override="TRUE">
<FieldRef Name="Test1" />
<FieldRef Name="Test2" />
</OrderBy>
<Where>
<Eq>
<FieldRef Name="Test3"/>
<Value Type="Text">1</Value>
</Eq>
</Where>
</Query>
<ViewFields>
<FieldRef Name="Attachments"></FieldRef>
<FieldRef Name="LinkTitle"></FieldRef>
<FieldRef Name="Test1"></FieldRef>
<FieldRef Name="Test2"></FieldRef>
<FieldRef Name="Test3"></FieldRef>
<FieldRef Name="Audience"></FieldRef>
</ViewFields>
<ParameterBindings>
<ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
<ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
</ParameterBindings>
</View>
Try to Put Where clause before the Order By Clause.
I am not 100% sure but give it a try

How do I create this type of Task List, with columns "Status" and "Description" instead of "Task Status" and "Body"?

I have 2 site collections, A and B.
In site collection A, when I create a new Task List, the columns are (I will call it "Type A"):
% Complete
Assigned To
Body (this one is different)
Due Date
Predecessors
Priority
Start Date
Task Group
Task Status (this one is different)
Title
Workflow Name
Created By
Modified By
In Site Collection B, the newly created Task List will have columns like this (I will call it "Type B"):
% Complete
Assigned To
Description (this one is different)
Due Date
Predecessors
Priority
Start Date
Status (this one is different)
Task Group
Title
Workflow Name
Created By
Modified By
It seems like these are two types of Task List. I use the same method to create the new task list:
Site Actions - More Options - (Filter by List) then select "Tasks"
There are some existing Type B Task List in Site Collection A, but when I create new ones, they are always Type A. How can I create Type B Task List in Site Collection A?
I hope this is not too confusing...
Thanks!
you can accomplish this requirement using your custom Content Types. you can inherited Task Content Type with your Custom Content Types.and than showing your Requirement field.
Here is showing Content Type IDs of Task : http://joelblogs.co.uk/2011/06/16/sharepoint-2010-base-types-list-template-and-definition-ids-and-content-types-ids/
create your content type from VS2010 like :
<ContentType ID="0x01080100FFbc98c2529347a5886b8d2576b954ef"
Name="Workflow 1 Tasks 1"
Group="Workflow 1 Tasks"
Description="Content Type of Tasks 1 of Workflow 1">
<FieldRefs>
<!-- OOTB Task Content Type -->
<FieldRef ID="{c042a256-787d-4a6f-8a8a-cf6ab767f12d}" Name="ContentType" />
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE" />
<FieldRef ID="{c3a92d97-2b77-4a25-9698-3ab54874bc6f}" Name="Predecessors" />
<FieldRef ID="{a8eb573e-9e11-481a-a8c9-1104a54b2fbd}" Name="Priority" />
<FieldRef ID="{c15b34c3-ce7d-490a-b133-3f4de8801b76}" Name="Status" />
<FieldRef ID="{d2311440-1ed6-46ea-b46d-daa643dc3886}" Name="PercentComplete" />
<FieldRef ID="{53101f38-dd2e-458c-b245-0c236cc13d1a}" Name="AssignedTo" />
<FieldRef ID="{7662cd2c-f069-4dba-9e35-082cf976e170}" Name="Body" />
<FieldRef ID="{64cd368d-2f95-4bfc-a1f9-8d4324ecb007}" Name="StartDate" />
<FieldRef ID="{cd21b4c2-6841-4f9e-a23a-738a65f99889}" Name="DueDate" />
<FieldRef ID="{58ddda52-c2a3-4650-9178-3bbc1f6e36da}" Name="WorkflowLink" />
<FieldRef ID="{16b6952f-3ce6-45e0-8f4e-42dac6e12441}" Name="OffsiteParticipant" />
<FieldRef ID="{4a799ba5-f449-4796-b43e-aa5186c3c414}" Name="OffsiteParticipantReason" />
<FieldRef ID="{18e1c6fa-ae37-4102-890a-cfb0974ef494}" Name="WorkflowOutcome" />
<FieldRef ID="{e506d6ca-c2da-4164-b858-306f1c41c9ec}" Name="WorkflowName" />
<FieldRef ID="{ae069f25-3ac2-4256-b9c3-15dbc15da0e0}" Name="GUID" />
<FieldRef ID="{8d96aa48-9dff-46cf-8538-84c747ffa877}" Name="TaskType" />
<FieldRef ID="{17ca3a22-fdfe-46eb-99b5-9646baed3f16}" Name="FormURN" />
<FieldRef ID="{78eae64a-f5f2-49af-b416-3247b76f46a1}" Name="FormData" />
<FieldRef ID="{8cbb9252-1035-4156-9c35-f54e9056c65a}" Name="EmailBody" />
<FieldRef ID="{47f68c3b-8930-406f-bde2-4a8c669ee87c}" Name="HasCustomEmailBody" />
<FieldRef ID="{cb2413f2-7de9-4afc-8587-1ca3f563f624}" Name="SendEmailNotification" />
<FieldRef ID="{4d2444c2-0e97-476c-a2a3-e9e4a9c73009}" Name="PendingModTime" />
<FieldRef ID="{35363960-d998-4aad-b7e8-058dfe2c669e}" Name="Completed" />
<FieldRef ID="{1bfee788-69b7-4765-b109-d4d9c31d1ac1}" Name="WorkflowListId" />
<FieldRef ID="{8e234c69-02b0-42d9-8046-d5f49bf0174f}" Name="WorkflowItemId" />
<FieldRef ID="{1c5518e2-1e99-49fe-bfc6-1a8de3ba16e2}" Name="ExtendedProperties" />
<!-- OOTB Task Content Type -->
<!-- Add your additional colums what you want. -->
</FieldRefs>
<XmlDocuments>
<XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<FormTemplates xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<Display>ListForm</Display>
<Edit>ListForm</Edit>
<New>ListForm</New>
</FormTemplates>
</XmlDocument>
</XmlDocuments>
</ContentType>
after create two custom content types. content Type A and content Type B and set it to Default when its required on your list.
Hops its helps!!!

Issue in using recurrence in SSRS / Dynamic Reports on Sharepoint lists

I am using Reporting Service with SharePoint List
I am querying a calendar list, i have issue fetching recurring items. When i try to use expand recurrence i get the following issue
The query for recurrence i have is:
<RSSharePointList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ListName>SomeList</ListName>
<Query>
<Where>
<DateRangesOverlap>
<FieldRef Name='EventDate' />
<FieldRef Name='EndDate' />
<FieldRef Name='RecurrenceID' />
<Value Type='DateTime'><Today/></Value>
</DateRangesOverlap>
</Where>
</Query>
<QueryOptions>
<ExpandRecurrence>TRUE</ExpandRecurrence>
<CalendarDate><Today/></CalendarDate>
<ViewAttributes Scope='RecursiveAll' />
</QueryOptions>
<ViewFields>
<FieldRef Name="EventDate" />
<FieldRef Name="EndDate" />
<FieldRef Name="fRecurrence" />
<FieldRef Name="Hosted_x0020_By" />
<FieldRef Name="External_x0020_Attendees" />
<FieldRef Name="Catering_x0020_Requirements" />
<FieldRef Name="Company" />
<FieldRef Name="Recurrence_x0020_ID" />
<FieldRef Name="Room" />
<FieldRef Name="RecurrenceData" />
</ViewFields>
</RSSharePointList>
is it proper? is there any other way to handle recurrence with Reporting Service? Kindly help.
Formed each XML tag by creating a new Parameter of the type XML.