Adding an entity key when no key is inferred from a view - entity-framework

I have a database view which joins across a number of tables in SQL Server 2005. It looks something like this:
SELECT
m1.MenuName AS menu_name, m2.MenuName AS sub_menu_name, p.ProductName, od.amount
FROM
dbo.tblMenus AS m1
FULL OUTER JOIN
dbo.tblMenus AS m2
FULL OUTER JOIN
dbo.tblProductsRelMenus AS pm ON m2.Id = pm.SubMenuId ON m1.Id = pm.MenuId
FULL OUTER JOIN
(SELECT
dbo.tblOrderDetails.ProductId, SUM(dbo.tblOrderDetails.Ammount) AS amount
FROM
dbo.tblOrderDetails
FULL OUTER JOIN
dbo.tblOrders AS o ON dbo.tblOrderDetails.OrderId = o.OrderId
WHERE (o.OrderDestroyed = 0)
GROUP BY dbo.tblOrderDetails.ProductId) AS od
RIGHT OUTER JOIN
dbo.tblProducts AS p ON od.ProductId = p.ProductId ON pm.ProductId = p.ProductId
When I try to create an ADO .Net entity data model it complains about not having a primary key in the SSDL secion. I then found this:
http://msdn.microsoft.com/en-us/library/dd163156.aspx
but I don't understand the part about a defining query. Surely I just want a column with unique numbers to define the key, or?
<EntityType Name="SoldItemsView">
<Key>
<PropertyRef Name="SoldItemsViewId" />
</Key>
<Property Name="SoldItemsView" Type="int" Nullable="false" />
<Property Name="menu_name" Type="nvarchar" MaxLength="100" />
<Property Name="sub_menu_name" Type="nvarchar" MaxLength="100" />
<Property Name="ProductName" Type="nvarchar" MaxLength="50" />
<Property Name="amount" Type="int" />
</EntityType>
But how do I populate this column with unique numbers?
Thanks,
Barry

You can use only columns from the view. To define an entity key you must select column (or set of columns) from your view which uniquely identifies record from the view.

Related

parameters in sql fragment substitute error

I write a sql fragment, like this:
<sql id="day">
<choose>
<when test="${property} == 'day'">
substring(datachange_createtime, 1, 10)
</when>
<otherwise>
${property}
</otherwise>
</choose>
</sql>
and include this sql like this:
select * from my_table
<if test="groupBy != null">
group by
<foreach collection="groupBy" item="groupByAttr" separator=",">
<include refid="day">
<property name="property" value="groupByAttr"/>
</include>
</foreach>
</if>
But I got an error, mybatis didn't substitute property with a real parameter, but with groupByAttr. The result sql is like:
select * from my_table group by groupByAttr
In the otherwise clause, if I replace ${property} with #{${property}}, The result sql becomes:
select * from my_table group by ?
It is indeed correct, but for some reasons, I don't want a prepared sql.
I think the problem is the behavior of substitution in test and otherwise clauses is different.
Is the a bug, or just some mistakes I took? How to solve this problem?
Short answer:
You need to change the <include /> as follows.
<sql id="day">
<choose>
<when test="${property} == 'day'">
substring(datachange_createtime, 1, 10)
</when>
<otherwise>
\\${${property}}
</otherwise>
</choose>
</sql>
Long answer:
With your original code, the statement will look as follows after the <include /> substitution.
select * from my_table
<if test="groupBy != null">
group by
<foreach collection="groupBy" item="groupByAttr" separator=",">
<choose>
<when test="groupByAttr == 'day'">
substring(datachange_createtime, 1, 10)
</when>
<otherwise>
groupByAttr
</otherwise>
</choose>
</foreach>
</if>
As you can see, <when /> is OK, but <otherwise /> is not.
<otherwise /> should look like this:
<otherwise>
${groupByAttr}
</otherwise>
In the expression in the short answer \\${${property}}, the first two backslashes is the escape syntax which avoids the outer ${} from being treated as a variable.
Note that #{groupByAttr} does not work here because, in java.sql.PreparedStatement, a placeholder ? is not allowed for a table/column name.
Please see the wiki page for the details.

Faceting in solr

Good day friends
I am facing a problem as I require to match the following query in solr
SELECT entidad, municipio, count(*) as total,
sum(case when ip like '10.%' then 1 else 0 end) as internos,
sum(case when ip not like '10.%' then 1 else 0 end) as externos
FROM bitacora.actividad a
where sistema = 'RGNPMarcas'
AND fecha >= '2021/07/16' and fecha <= '2021/07/31'
AND parametros like 'PDF'
and parametros like 'EGV'
and entidad = '01'
GROUP BY entidad, municipio
ORDER BY entidad, municipio
I have been researching on Faceting in solr, I have come to make some counts like the following, but the truth is that I have no idea how to mitigate this situation.
My schema is the following:
<field name="tabla" type="string" indexed="true" stored="false" multiValued="false"/>
<field name="entidad" type="string" indexed="true" stored="true" default="" multiValued="false"/>
<field name="municipio" type="string" indexed="true" stored="true" default="" multiValued="false"/>
<field name="ip" type="text_general" indexed="true" stored="true" default="" multiValued="false"/>
<field name="fecha" type="pdate" indexed="true" stored="true" multiValued="false" default=""/>
<field name="parametros" type="text_general" indexed="true" stored="true" default="" multiValued="false"/>
<field name="total" type="pint" uninvertible="true" indexed="true" stored="true"/>
<field name="internos" type="pint" uninvertible="true" indexed="true" stored="true"/>
<field name="externos" type="pint" uninvertible="true" indexed="true" stored="true"/>
As you can see, I already have the base and the indexed fields, what I need is your experience on these issues of solr or that someone can guide me, please!
if you could have one field with the name "ip_type" and the content "Internos" or "Externos" depending on weather or not the ip starts with "10.", then your query will have as Filter Query all the conditions you wrote after "where" (for instance "sistema = 'RGNPMarcas'") and the facet pivot would have 3 fields: "entidad,municipio,ip_type".
Now, in order to obtain the "ip_type" column, you can either change the way you index data (alter the input), or you can use a pattern replace char filter factory (https://solr.apache.org/guide/7_1/charfilterfactories.html#solr-patternreplacecharfilterfactory)

Postgres XML parsing - Calculate the sum of multiple nodes of the same name using XPath

I have an xml snippet as below:
<OpCodeLaborInfo JobStatus="F" UpSellFlag="N" JobNo="1" OpCode="02TTZ10K" OpCodeDesc="10K SERVICE">
<TechInfo ActualHrsWorked="2.50" CustTechRate="27.00" TechHrs="0.00" TechName="JEFF SELLERS" TechNo="4816" />
<TechInfo ActualHrsWorked="0.00" CustTechRate="27.00" TechHrs="0.70" TechName="JEFF SELLERS" TechNo="4816" />
<BillTimeRateHrs BillRate="129.97" />
<CCCStmts Correction="PERFORMED 10K SERVICE" Complaint="LUBE OIL FILTER CHANGE, TIRE ROTATION, PERFORM MULTI POINT" />
<CCCStmts Correction="X" Complaint="INSPECTION, INSPECT FILTERS AND RECOMMEND, INSPECT BRAKES," />
<CCCStmts Complaint="BELTS AND HOSES" />
<RoAmts DlrCost="18.90" PayType="Cust" AmtType="Job" TotalAmt="59.12" />
</OpCodeLaborInfo>
<OpCodeLaborInfo JobStatus="F" UpSellFlag="N" JobNo="2" OpCode="02TTZ10K" OpCodeDesc="10K SERVICE">
<TechInfo ActualHrsWorked="2.50" CustTechRate="27.00" TechHrs="1.00" TechName="JEFF SELLERS" TechNo="4816" />
<TechInfo ActualHrsWorked="0.00" CustTechRate="27.00" TechHrs="0.00" TechName="JEFF SELLERS" TechNo="4816" />
<BillTimeRateHrs BillRate="129.97" />
<CCCStmts Correction="PERFORMED 10K SERVICE" Complaint="LUBE OIL FILTER CHANGE, TIRE ROTATION, PERFORM MULTI POINT" />
<CCCStmts Correction="X" Complaint="INSPECTION, INSPECT FILTERS AND RECOMMEND, INSPECT BRAKES," />
<CCCStmts Complaint="BELTS AND HOSES" />
<RoAmts DlrCost="18.90" PayType="Cust" AmtType="Job" TotalAmt="59.12" />
</OpCodeLaborInfo>
I need to calculate the sum of the TechInfo/#TechHrs for each OpCodeLaborInfo. I tried the following:
unnest(xpath('sum(//dns:RepairOrder/dns:RoRecord/dns:Rolabor/dns:OpCodeLaborInfo/dns:TechInfo/#TechHrs[1])'::text,
data_detail.ro_data_xml,
ARRAY[ARRAY['dns'::text, 'http://www.starstandards.org/STAR'::text]]))::text::numeric AS lbrsoldhours
but this seems to return the sum of the Tech Hours inside both the OpCodeLaborInfo nodes. Could someone be able to tell me how I can tweak the xpath so as to get the desired result.
So basically I need :
Job
Tech Hrs
1
sum(0.00+0.70)
2
sum(1.00+0.00)
I would solve this using xmltable()
select d.job, sum(t.hours)
from data_detail d
cross join xmltable (
'/OpCodeLaborInfo/TechInfo'
passing d.ro_data_xml
columns hours numeric path '#TechHrs') as t
group by d.job;
Online example
The XPath is probably not correct as the XPath you have shown doesn't match your sample XML data. Your sample XML also doesn't contain a namespace, so I am not sure why you are passing one to xpath()
But if you need one, you can use something like this:
cross join xmltable (
xmlnamespaces ('http://www.starstandards.org/STAR' as dns),
'/dns:OpCodeLaborInfo/dns:TechInfo'
passing d.ro_data_xml
columns hours numeric path '#TechHrs') as t
xpath can also work fine:
SELECT job
, SUM((xpath('//#TechHrs', element))[1]::text::decimal)
FROM data_detail
, LATERAL (SELECT unnest(xpath('/OpCodeLaborInfo/TechInfo', ro_data_xml))) u(element)
GROUP BY job;
fiddle
(based on the fiddle of #a_horse_with_no_name)

How can I convert this T-SQL to Fetch-XML?

I want to use this SQL in a Dynamics CRM report. I can't work out how to convert it to Fetch-XML.
select p.ProductNumber "Plan Number",p.Name,p.price "Monthly Rate",count(*) "Group", '0' "Direct Debit"
from contact c,product p
where c.integ_schemeid = p.ProductId
and c.ParentCustomerId is not null
group by p.ProductNumber,p.Name,p.price
union
select p.ProductNumber "Plan Number",p.Name,p.price "Monthly Rate", '0' "Group", count(*) "Direct Debit"
from contact c,product p
where c.integ_schemeid = p.ProductId
and c.ParentCustomerId is null
group by p.ProductNumber,p.Name,p.price
http://www.sql2fetchxml.com fails on this occasion.
You can't convert that query to FetchXML, because unions aren't supported. What you'll need to do is look into merging the queries into 1 if possible. Even if it means duplicating columns and using conditional statements within your report to display the relevant data instead. For example, if you simplified the query to this:
select p.ProductNumber "Plan Number", p.Name, p.price, c.ParentCustomerId
from product p
inner join contact c on c.integ_schemeid = p.ProductId
This can be converted to the following fetchxml:
<fetch mapping="logical">
<entity name="product">
<attribute name="ProductNumber" alias="Plan Number" />
<attribute name="Name" />
<attribute name="price" />
<link-entity name="contact" to="ProductId" from="integ_schemeid" alias="c" link-type="inner">
<attribute name="ParentCustomerId" />
</link-entity>
</entity>
</fetch>
Then, because you have all of the data in 1 dataset including contacts with null ParentCustomerIds, you can group within your report instead of within the query.

OLAP/MDX - define calculated member, sum all time to date data

I would like to define "all time to date" calculated member in OLAP cube. I'm able to calculate YTD by using the following:
SUM(YTD([Time].[Month].CurrentMember), [Measures].[Suits])
How can I include all dates since the beginning of my data? My time dimension looks like:
<Dimension type="TimeDimension" visible="true" foreignKey="granularity" highCardinality="false" name="Time">
<Hierarchy name="Time" visible="true" hasAll="true" primaryKey="eom_date">
<Table name="v_months" schema="bizdata">
</Table>
<Level name="Year" visible="true" column="year_number" type="String" uniqueMembers="false" levelType="TimeYears" hideMemberIf="Never">
</Level>
<Level name="Quarter" visible="true" column="quarter_number" type="String" uniqueMembers="false" levelType="TimeQuarters" hideMemberIf="Never">
</Level>
<Level name="Month" visible="true" column="month_number" type="String" uniqueMembers="false" levelType="TimeMonths" hideMemberIf="Never">
</Level>
</Hierarchy>
</Dimension>
Not sure if relevant: I'm using mondrian olap server (running on tomcat), Saiku as frontend, postgres as database
I've tried a lot of combinations, but I can't figure it out.
Update: I've tried to use syntax suggested by Gonsalu:
<CalculatedMember name="YTD Suits" formatString="" formula="SUM(YTD([Time].[Month].CurrentMember), [Measures].[Suits])" dimension="Measures" visible="true">
</CalculatedMember>
<CalculatedMember name="PTD Suits" formatString="" formula="Sum({NULL:[Time].[Month].CurrentMember },[Measures].[Suits])" dimension="Measures" visible="true">
</CalculatedMember>
Using this I get the following error message when starting mondrian (note that YTD function works well without the second calculated member):
Caused by: mondrian.olap.MondrianException: Mondrian Error:Failed to parse query
'WITH
MEMBER [Measures].[Measures].[YTD Suits]
AS 'SUM(YTD([Time].[Month].CurrentMember), [Measures].[Suits])',
[$member_scope] = 'CUBE',
MEMBER_ORDINAL = 6
MEMBER [Measures].[Measures].[PTD Suits]
AS 'Sum({NULL:[Time].[Month].CurrentMember },[Measures].[Suits])',
[$member_scope] = 'CUBE',
MEMBER_ORDINAL = 7
SELECT FROM [Project Performance]'
Thank you for any ideas.
I haven't used Mondrian, but in SQL Server Analysis Services (SSAS), using the NULL member causes the range to go from one end of the level to the specified member.
In your case, the calculated member you're looking for might be something like this:
Sum( { NULL : [Time].[Month].CurrentMember }
, [Measures].[Suits]
)
You could also do a to the end of times calculated member using the NULL member on the other end, like so:
{ [Time].[Month].CurrentMember : NULL }
You can use PeriodsToDate function along with the allMember.
In your case it would be:
PeriodsToDate([Time.Time].[all_Time_member_name],[Time.Time].CurrentMember)