How to join dbo.LocalizedLabelView to get form labels in Dynamics CRM? - sql

In Dynamics CRM, I often get requirements from business users to create reports. Business users know and speak about entity display names and attribute labels. To write a query, I need to map those to entity names and attribute names. I would like to use a query to look this up.
To what do I join the dbo.LocalizedLabelView view to get the AttributeLabel column in the following query? I can't figure out what ObjectId is supposed to reference. (And if you can tell me how you figured out the answer I'd be especially appreciative!)
select
[EntityName] = entityNames.Name,
[EntityDisplayName] = entityDisplayNames.Label,
[AttributeName] = attributeNames.PhysicalName,
[AttributeDisplayName] = attributeDisplayNames.Label
--[AttributeLabel] = attributeLabels.Label
from
dbo.EntityView entityNames
inner join dbo.LocalizedLabelView entityDisplayNames
on entityDisplayNames.ObjectId = entityNames.EntityId
and entityDisplayNames.ObjectColumnName = 'LocalizedName'
left outer join dbo.AttributeView attributeNames
on attributeNames.EntityID = entityNames.EntityID
inner join dbo.LocalizedLabelView attributeDisplayNames
on attributeDisplayNames.ObjectId = attributeNames.AttributeID
and attributeDisplayNames.ObjectColumnName = 'DisplayName'
and attributeDisplayNames.LanguageID = entityDisplayNames.LanguageID
--inner join dbo.LocalizedLabelView attributeLabels
-- on attributeLabels.ObjectId = ?????
-- and attributeLabels.LanguageID = entityDisplayNames.LanguageID
where
entityDisplayNames.LanguageID = 1033
order by
entityDisplayNames.Label,
attributeDisplayNames.Label

ObjectId is a reference to the internal ID of a thing in the CRM database. This thing can be an attribute, entity, label, or whatever.
Since you want the label for your attribute, use that attribute's id as the ObjectId here. I think that you want your join condition to look like this:
inner join dbo.LocalizedLabelView attributeLabels
on attributeLabels.ObjectId = attributeNames.AttributeID
and attributeLabels.LanguageID = entityDisplayNames.LanguageID
and attributeLabels.ObjectColumnName = 'DisplayName'
If you want the description for the attribute, you can change the ObjectColumnName to 'Description'.

Related

multi-inner join statement

I'm currently trying to draw multiple tables through several inner-join statements. However, I am continually hit with the following error:
ORA-00904: "PART"."ITEM_CLASS": invalid identifier
I've visited several other pages here but that problem did not coincide with mine.
Here is the SQL query:
SELECT Slsrep_Number, AVG(Commission_Rate) AS AVG_Rate, MAX(Total_Commission) as MAX_Comission
FROM Sales_Rep
WHERE Sales_Rep.Slsrep_Number = Customer.Slrsrep_Number
AND Customer.C_Number = Orders.C_Number
AND Orders.Order_Number = Order_Line.Order_Number
AND Order_Line.Part_Number = Part.Part_Number
AND Part.Item_Class = 'SG';
Here are the tables being used (screenshots):
The pictures are listed in the order that I am referencing them in the SQL query.
You need to reference the tables in the FROM clause. You can't just reference them.
You should also use table aliases and proper, explicit, standard JOIN syntax.
So:
SELECT sr.Slsrep_Number,
AVG(?.Commission_Rate) AS AVG_Rate,
MAX(?Total_Commission) as MAX_Comission
FROM Sales_Rep sr JOIN
Customer c
ON sr.Slsrep_Number = c.Slrsrep_Number JOIN
Orders o
ON c.C_Number = o.C_Number JOIN
Order_Line ol
ON o.Order_Number = ol.Order_Number
Part p
ON ol.Part_Number = p.Part_Number
WHERE p.Item_Class = 'SG';
The ? is for the alias for the column with the commission.
The query now "looks" right. However, I don't think it is particularly useful. If that is the case, ask another question and provide sample data, desired results, and an explanation of what you want to accomplish.
Customer,Orders,Order_Line and Part Tables are missing in the from clause.Try This.
SELECT Slsrep_Number,
AVG(Commission_Rate) AS AVG_Rate,
MAX(Total_Commission) as MAX_Comission
FROM Sales_Rep,Customer,Orders,Order_Line,Part
WHERE Sales_Rep.Slsrep_Number = Customer.Slrsrep_Number
AND Customer.C_Number = Orders.C_Number
AND Orders.Order_Number = Order_Line.Order_Number
AND Order_Line.Part_Number = Part.Part_Number
AND Part.Item_Class = 'SG';

How to get a data in a Text field in SSRS if the dataset does not contain the value?

I have four dataset in SSRS. They are below-
POHeader- Company, PONum
PODetail- Company, PONum, POLine
PORel- Company, JobNum, POLine, PONum, ProjectID
JobHead- Company, JobCOde, JobNum, PersonID, ProjectID
There is a text field (Project Lead) in the POHeader in which I want to show the person ID (Project Lead Name). However, POHeader does not contain any PersonID field. One way I am thinking to do that is relate POHeader and PORel tables that will match PONum and return JobNum and the Returned JobNUm will be matched with JobHead.JobNum.
If they match and then the PersonID will be returned, which will be shown in the text field (Project Lead) in the POHeader.
However, I have little experience in SQL. Would be great if someone can help me in this regard.
LOOKUP function can be a solution here, but comparing one return value with an existing value of a different data seems challenging for me.
UPDATE on the SQL Code-
="SELECT
[PlannerID].[JobHead_PersonID] as [JobHead_PersonID]
from (select
[POHeader].[PONum] as [POHeader_PONum],
[JobHead].[PersonID] as [JobHead_PersonID],
[JobHead].[JobNum] as [JobHead_JobNum]
from Erp.POHeader as POHeader
inner join Erp.PODetail as PODetail on
POHeader.Company = PODetail.Company
and POHeader.PONum = PODetail.PONUM
inner join Erp.PORel as PORel on
PODetail.Company = PORel.Company
and PODetail.PONUM = PORel.PONum
and PODetail.POLine = PORel.POLine
inner join Erp.JobHead as JobHead on
PORel.Company = JobHead.Company
and PORel.JobNum = JobHead.JobNum) as PlannerID
right outer join Erp.POHeader as POHeader1 on
POHeader1.PONum = PlannerID.POHeader_PONum
POHeader.Company = PODetail.Company
and POHeader.PONum = PODetail.PONUM
inner join Erp.PORel as PORel on
PODetail.Company = PORel.Company
and PODetail.PONUM = PORel.PONum
and PODetail.POLine = PORel.POLine
inner join Erp.JobHead as JobHead on
PORel.Company = JobHead.Company
and PORel.JobNum = JobHead.JobNum) as PlannerID
right outer join Erp.POHeader as POHeader1 on
POHeader1.PONum = PlannerID.POHeader_PONum"
SQL Code that I have written to return the PersonID, but I need to know two things-
Where to put this subquery?
How to return the value from the subquery in the Project Lead text field using an expression?
Will be grateful if I can get some suggestions. Thanks
SSRS uses Datasets to get data from a database, and each field in a data set can be displayed on a report. To add a field to a dataset, it must be returned by the underlying data set query. View the data set properties and look at the query. If it is of the form "select a,b,c from table", add the field you want to the column list (a,b,c etc). If it is a stored procedure, find someone who can edit that procedure to include your missing field. When you have done this, refresh the field list for the Dataset. Your new field should be usesable in the report now. Of course, if you have broken the sql for the data set you will need to find someone who knows the underlying database to help you.

Merge trying to join a table to itself

I have a Story model and a Tag model, which has_and_belongs_to_many each other. Tags have a field called adult, which indicates that any story that has that tag contains adult content. Story has a field called adult_override, which indicates that it has adult content even if none of its tags are adult. I have the following function, which takes an ActiveRecord::Relation representing a set of stories and filters it to include only adult stories (this is a method of the Story class):
def self.only_adult(story_set)
story_set.left_outer_joins(:tags)
.distinct
.where("stories.adult_override = true OR tags.adult = true")
end
I also have a function that is supposed to take a given set of stories (an ActiveRecord::Relation) and find the most common tags in that set (this is a method of the Tag class):
def self.most_common(story_set, num = 10)
joins(:stories).merge(story_set)
.select("tags.*, COUNT(*) AS cnt")
.group("tags.name")
.reorder("cnt DESC")
.limit(num)
end
(name is the primary key of the tags table)
These methods both work fine on their own, but when I try to call most_common on a relation that's already been filtered by only_adult, I get the following error:
Can't join 'Tag' to association named 'tags'; perhaps you misspelled
it?
How do I get most_common to work even if the tags table is already referenced in the story_set it's being passed?
Edit: the SQL generated by Tag.joins(stories) is:
SELECT "tags".* FROM "tags" INNER JOIN "stories_tags" ON
"stories_tags"."name" = "tags"."name" INNER JOIN "stories" ON
"stories"."id" = "stories_tags"."story_id"
and the SQL generated by only_adult is, in one example:
SELECT DISTINCT "stories".* FROM "stories" LEFT OUTER JOIN
"stories_tags" ON "stories_tags"."story_id" = "stories"."id" LEFT
OUTER JOIN "tags" ON "tags"."name" = "stories_tags"."name" WHERE
(true) AND (EXISTS (SELECT 1 FROM characters_stories INNER JOIN
characters ON characters_stories.character_id = characters.id WHERE
(characters_stories.story_id = stories.id) AND (LOWER(characters.name)
SIMILAR TO 'doc%'))) AND (stories.adult_override = true OR tags.adult
= true) ORDER BY "stories"."author" ASC
The problem occurs when these two relationships are merged.
Okay, I figured out how to get this working properly, so I'll add my solution in case anyone else has a similar problem. I replaced the body of most_common with (editing a bit for simplicity):
rflct = reflect_on_association(:stories)
join_table = rflct.join_table
join_sql = "INNER JOIN #{join_table} AS jt ON " +
"jt.#{rflct.foreign_key} = " +
"answer.name}"
processed_set = story_set.where("stories.id = jt.#{rflct.association_foreign_key}")
self.select('answer.*, COUNT(*) as cnt')
.from("tags AS answer")
.joins(join_sql)
.where("EXISTS (#{processed_set.to_sql})")
.group("answer.tags")
.reorder('cnt DESC')
.limit(num)
I'm not entirely happy with this -- I feel like there's probably a more elegant way to accomplish this -- but it does work.

VB.NET Reportviewer How to make Inner Join work properly

I have 2 tables
tableAssembly, with columns SerialNumber, Brick1SerialNumber, Brick2SerialNumber,DateInserted
tableBricks, with columns SerialNumber, Lot, Weight, DateMeasured
In VB.NET(WinForms) I have been able to get the reportviewer control to work and print out information from both tables and also to enable/disable columns, and apply filters such as LIKE
In case it isn't clear tableAssembly.Brick1SerialNumber = tableBricks.SerialNumber
What I now want to do is when a user prints out a report from tableAssembly, I want them to be able to filter based on Brick1SerialNumber.Lot or Brick2SerialNumber.Lot or Brick1SerialNumber.DateMeasured or Brick2SerialNumber.DateMeasured
I understand I need to INNER JOIN tableAssembly.Brick1SerialNumber = tableBricks.SerialNumber AND tableAssembly.Brick2SerialNumber = tableBricks.SerialNumber
Do I also need to INNER JOIN the other columns from tableBricks to columns in tableAssembly? or does the INNER JOIN of Brick1SerialNumber = SerialNumber and Brick2SerialNumber = Serial make it so I can filter based on .Lot?
There are two ways to approach this. 1) join to tableBricks twice (probably not necessary for this condition) or attach it once, using both foreign keys (works for this condition, but not for all conditions).
Try this query:
SELECT tableAssembly.*
FROM tableAssembly INNER JOIN tableBricks
ON tableAssembly.Brick1SerialNumber = tableBricks.SerialNumber
OR tableAssembly.Brick2SerialNumber = tableBricks.SerialNumber
WHERE tableBricks.Lot = 99 --actually means Brick1.Lot or Brick2.Lot
AND tableBricks.DateMeasured = '1/1/2000'
If you need a specific Lot or DateMeasured for Brick1 and Brick2 (not the same values), then try this query:
SELECT tableAssembly.*
FROM tableAssembly INNER JOIN tableBricks AS tableBricks1
ON tableAssembly.Brick1SerialNumber = tableBricks1.SerialNumber
INNER JOIN tableBricks AS tableBricks2
ON tableAssembly.Brick2SerialNumber = tableBricks2.SerialNumber
WHERE tableBricks1.Lot = 98
AND tableBricks2.Lot = 99
AND tableBricks1.DateMeasured = '1/1/2000'
AND tableBricks2.DateMeasured = '1/2/2000'

SQL Query that sorts information into two new columns based on a third column

I have a table that stores basic site information, another one that stores the site address, and a third table for the phone. My phone table contains phone numbers, and the type of number.
What I want to do is get my site information, and the main contact number and fax number. So far, my statement looks like this:
SELECT site.isiteid,
site.iclientid,
csitecode,
csitename,
binactive,
caddress1,
caddress2,
ccity,
cstateid,
czip,
icountryid,
cattention,
cemail,
cnumber,
cextension
FROM dbo.site
INNER JOIN dbo.address
ON dbo.site.isiteid = dbo.address.isiteid
AND (site.isiteid = 2)
LEFT JOIN dbo.phone
ON dbo.site.isiteid = dbo.phone.isiteid
AND (dbo.phone.iphtypeid = 1)
This gets me all of the information that I need except for the fax number (dbo.phone.iphtypeid=3). Is there a way to add another column to the result called [fax], and populate it when site.isiteid=phone.isiteid AND phone.iphtypeid=3? Thus, the last 4 columns returned would be [cemail][cnumber][cextension][cfax].
RESOLVED
Thank you to all three who answered. All the answers were similar, so I selected the one that had the most detailed explanation. I did need to add the table name to both cnumber references and cextension to avoid ambiguity. Thank you for the responses!
Add another JOIN clause
LEFT JOIN dbo.phone f
ON dbo.site.isiteid = f.isiteid
AND f.iphtypeid = 3
You would then add f.cfax to the SELECT list.
It might also be good to give the other tables aliases so you can distinguish which columns are coming from which tables.
Yes, you can do this by adding another join to dbo.phone. To distinguish between the two uses, you will need to give the second join an alias. So, something like:
SELECT site.isiteid,
site.iclientid,
csitecode,
csitename,
binactive,
caddress1,
caddress2,
ccity,
cstateid,
czip,
icountryid,
cattention,
cemail,
phone.cnumber,
phone.cextension,
phone_fax.cnumber AS cfax
FROM dbo.site
INNER JOIN dbo.address
ON dbo.site.isiteid = dbo.address.isiteid
AND (site.isiteid = 2)
LEFT JOIN dbo.phone
ON dbo.site.isiteid = dbo.phone.isiteid
AND (dbo.phone.iphtypeid = 1)
LEFT JOIN dbo.phone AS phone_fax
ON dbo.site.isiteid = phone_fax.isiteid
AND (phone_fax.iphtypeid = 3)
You could do something like, even though I'm not sure of how you're tables are defined.
SELECT site.isiteid,
site.iclientid,
csitecode,
csitename,
binactive,
caddress1,
caddress2,
ccity,
cstateid,
czip,
icountryid,
cattention,
cemail,
cnumber,
cextension,
CASE WHEN C.iphtypeid = 3 THEN C.cnumber ELSE NULL END [cfax]
FROM dbo.site A
INNER JOIN dbo.address
ON dbo.site.isiteid = dbo.address.isiteid
AND (site.isiteid = 2)
LEFT JOIN dbo.phone C
ON A.isiteid = C.isiteid