Showing posts with label relationship. Show all posts
Showing posts with label relationship. Show all posts

Wednesday, March 28, 2012

mapping a relationship to bulkload

I have the following document:

<customers>
<customer>
<name>xyz</name>
<address>1, Sacramento st</address>
<customer>
<customers>

I

want to map to the customer name to the customer(id, name, addr_id).

But the address to go custaddr table which has custaddr(id, address)

and the custaddr(id) goes to customer(addr_id ). I would like some

pointers to write a schema mapping for doing this.

I can change the xml format but I can't change the database design. Is it possible to do bulkload of this using XML Bulk load?

Thanks

vln
Hi ...

The link to this thread might help ...

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=174122&SiteID=1

Below is the Bulk Load implementation in C++.

Thanks,

Chris
Hi ...

I posted a question about Bulk Loading Xml data using C++ and the

SQLXMLBulkLoad.SQLXMLBulkload.3.0 COM Component. Below is the C++ code

that will do this. I have also included the xml, xsd and table

definition.
void CTestMeteorlogixApp::OnTestMsXmlBulkLoadRwis()

/* ///////////////////////////////////////////////////////////////////////

Method: CTestMeteorlogixApp::OnTestMsXmlBulkLoadRwis()

Description:

Microsoft XML Core Services (MSXML) offers several programmatic

extensions for writing XML applications. We will play with some

of these COM methods here.

Parameters: None

Return: None

Note:

Some of the code in this mehtod was derived from the following

discussion on xml:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sqlxml3/htm/bulkload_7pv0.asp

Notes: ISQLXMLBulkLoad


We had to do a little work to get the ISQLXMLBulkLoad object in here.

First we installed the XMLSQL Component onto the computer. After this

we needed to find the dll that we are going to import. You will

find the import (#import <xblkld3.dll>) in stdafx.h.

We then added the code below thinking that we could create the

object this way. This did not work. We will talk about this

alitttle more later.

ISQLXMLBulkLoad pISQLXMLBulkLoad = NULL;

pXMLDoc.CreateInstance("SQLXMLBulkLoad.SQLXMLBulkload.3.0");

Using the object viewer in Visual Studio [Tools]+[OLE/COM Obejct Viewer]

we were able to find the SQLXMLBulkLoad Class. From this we were able

to find the path where the dll is located an then look at the

IDL by viewing the TypeLib of the Class [File]+[View TypeLib...].

Looking at the IDL I decided that I would implement the object

as I would from an COM class using the progID[] and CoCreateInstance().

So in the end that is what we have done and the code is below. We

are still testing but it all is working. Note that we also looked

at the readme.txt from from the SQLXML install and then have

noted that they copyed the following files and I know that we would be

needed these to implment the COM interface.

// You will need these.

// C:\Program Files\SQLXML 3.0\include:

Xmlblkld.h

Xmlblkld_i.c

/////////////////////////////////////////////////////////////////////// */

{

int nDataCount = 0;

int nCount = 0;

long nIndex = 0;

long nIndex2 = 0;

CString csErrorMessage;

CString csLogMessage;

CString csMethodName;

CString csMessage;

CString csXmlSchemaFile("C:\\Macgowan\\Project\\TestMeteorlogix\\Data\\rwis_oh.xsd");

CString csXmlDataFile("C:\\Macgowan\\Project\\TestMeteorlogix\\Data\\rwis_oh.xml");

CString

csXmlErrorLogFile("C:\\Macgowan\\Project\\TestMeteorlogix\\Data\\rwis_oh.err");

CString csTableName1("Alphanumericdata.dbo.MacgowanTestRWISRawAtmospheric");

CString csTableName2("Alphanumericdata.dbo.MacgowanTestRWISRawSurface");

CString csProvider("sqloledb");

CString csDataSource("SQLDEV");

CString csDatabase("Alphanumericdata");

CString csUserId("cmacgowan");

CString csPassword("7498757");

_bstr_t bstrXmlData;

_bstr_t bstrConnect;

_bstr_t bstrXmlSchemaFile;

_bstr_t bstrXmlDataFile;

_bstr_t bstrXmlErrorLogFile;

_bstr_t bstrSql;

variant_t vResult;

variant_t vXmlDataFile;

HRESULT hResult;

CString csXmlData;

CString csTemp;

CString csTemp2;

CString csResult;

CString csConnect;

CString csSql;

// Define ADO connection pointers

_ConnectionPtr pConnection = NULL;

CMainFrame *pMainFrame = (CMainFrame *)AfxGetMainWnd();

CFrameWnd* pChild = pMainFrame->GetActiveFrame();

CTestMeteorlogixView* pView = (CTestMeteorlogixView*)pChild->GetActiveView();

pView->WriteLog("Start OnTestMsXmlBulkLoadRwis().");

try

{

CoInitialize(NULL);

// Tell the user what is going on ...

pView->WriteLog("Bulk

load xml using the SQLXMLBulkLoad.SQLXMLBulkload.3.0 COM Object");

csLogMessage.Format("Schema file: %s", csXmlSchemaFile);

pView->WriteLog(csLogMessage);

csLogMessage.Format("Data file: %s", csXmlDataFile);

pView->WriteLog(csLogMessage);

csLogMessage.Format("Error log file: %s", csXmlErrorLogFile);

pView->WriteLog(csLogMessage);
// When we open the application we will open the ADO connection

pConnection.CreateInstance(__uuidof(Connection));

// Set the connection string

csConnect.Format("provider=%s;data Source=%s;database=%s;uid=%s;pwd=%s",


csProvider,


csDataSource,


csDatabase,


csUserId,


csPassword);

bstrConnect = csConnect.AllocSysString();

// Open the ado connection

pConnection->Open(bstrConnect,"","",adConnectUnspecified);

// Convert filenames from CString to varients

bstrXmlSchemaFile = csXmlSchemaFile.AllocSysString();

bstrXmlDataFile = csXmlDataFile.AllocSysString();

vXmlDataFile.SetString(LPCTSTR(csXmlDataFile));

bstrXmlErrorLogFile = csXmlErrorLogFile.AllocSysString();

char progID[] = "SQLXMLBulkLoad.SQLXMLBulkload.3.0";

// Now make that object.

CLSID clsid;

wchar_t wide[80];

mbstowcs(wide, progID, 80);

CLSIDFromProgID(wide, &clsid);

ISQLXMLBulkLoad* pISQLXMLBulkLoad = NULL;


if(SUCCEEDED(CoCreateInstance(clsid, NULL, CLSCTX_ALL,

IID_ISQLXMLBulkLoad, (void**)&pISQLXMLBulkLoad)))

{


hResult = pISQLXMLBulkLoad->put_ConnectionString(bstrConnect);


hResult = pISQLXMLBulkLoad->put_BulkLoad((bool)TRUE);


hResult = pISQLXMLBulkLoad->put_ErrorLogFile(bstrXmlErrorLogFile);


hResult = pISQLXMLBulkLoad->put_KeepIdentity((bool)FALSE);


hResult = pISQLXMLBulkLoad->Execute(bstrXmlSchemaFile, vXmlDataFile);

if (SUCCEEDED(hResult))

{


pView->WriteLog("pISQLXMLBulkLoad->Execute() was successful.");

}

else

{


pView->WriteLog("Error: pISQLXMLBulkLoad->Execute()

failed.");

}

}

else

{


AfxMessageBox("Error: We could not find the ProgID!");

}

}

catch(_com_error *e)

{

CString Error = e->ErrorMessage();

AfxMessageBox(e->ErrorMessage());

pView->WriteLog("Error processing TestDatabase().");

}

catch(...)

{

pView->WriteLog("Error processing TestDatabase().");

}

pView->WriteLog("End OnTestMsXmlBulkLoadRwis().");

CoUninitialize();

return;

}
///////////////////////////////////////////////////////////////////////

// xsd schema

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:sql="urn:schemas-microsoft-com:mapping-schema">

<xsd:element name="site" sql:relation="MacgowanTestRWISRawAtmospheric" >

<xsd:complexType>

<xsd:attribute name="sysid" type="xsd:string" sql:field="SystemId"/>

<xsd:attribute name="rpuid" type="xsd:string" sql:field="RpuId"/>

</xsd:complexType>

</xsd:element>


<xsd:element name="atmospheric" sql:relation="MacgowanTestRWISRawAtmospheric" >

<xsd:complexType>

<xsd:attribute name="datetime" type="xsd:date" sql:field="ObsDateTime"/>

<xsd:attribute name="airtemp" type="xsd:string" sql:field="Temperature"/>

<xsd:attribute name="dewpoint" type="xsd:string" sql:field="DewPoint"/>

</xsd:complexType>

</xsd:element>

</xsd:schema>
///////////////////////////////////////////////////////////////////////

// xml data

<?xml version="1.0"?>

<odot_rwis_site_info>

<site id="200000" number="1" sysid="200" rpuid="0"

name="1-SR127 @. SR249" longitude="-84.554946" latitude="41.383527">

<atmospheric datetime="12/05/2005 03:48:00 PM"

airtemp="-490" dewpoint="-800" relativehumidity="73" windspeedavg="11"

windspeedgust="19" winddirectionavg="265" winddirectiongust="295"

pressure="65535" precipitationintensity="None" precipitationtype="None"

precipitationrate="0" precipitationaccumulation="-1" visibility="2000"

/>

<sensors>

<surface id="0" datetime="12/05/2005

03:48:00 PM" name="North Bound Driving Lane" surfacecondition="Dry"

surfacetemp="1900" freezingtemp="32767" chemicalfactor="255"

chemicalpercent="255" depth="32767" icepercent="255"

subsurfacetemp="450" waterlevel="0">

<traffic

datetime="12/05/2005 03:48:00 PM" occupancy="0" avgspeed="82"

volume="21" sftemp="1900" sfstate="255">

<normalbins>


<bin datetime="12/05/2005 03:48:00 PM" binnumber="0" bincount="7"

/>


<bin datetime="12/05/2005 03:48:00 PM" binnumber="1" bincount="0"

/>

</normalbins>

<longbins>


<bin datetime="12/05/2005 03:48:00 PM" binnumber="2" bincount="0"

/>


<bin datetime="12/05/2005 03:48:00 PM" binnumber="3" bincount="0"

/>


<bin datetime="12/05/2005 03:48:00 PM" binnumber="4" bincount="1"

/>


<bin datetime="12/05/2005 03:48:00 PM" binnumber="5" bincount="0"

/>

</longbins>

</traffic>

</surface>

<surface id="1" datetime="12/05/2005

03:48:00 PM" name="Bridge Deck Simulator" surfacecondition="Other"

surfacetemp="-60" freezingtemp="32767" chemicalfactor="255"

chemicalpercent="255" depth="32767" icepercent="255"

subsurfacetemp="-999999" waterlevel="0" />

</sensors>

</site>

</odot_rwis_site_info>
///////////////////////////////////////////////////////////////////////

// table definition

CREATE TABLE [MacgowanTestRWISRawAtmospheric] (

[RecordId] [int] IDENTITY (1, 1) NOT NULL ,

[DataSourceId] [char] (4)

COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT

[DF_MacgowanTestRWISRawAtmospheric_DataSourceId] DEFAULT ('OH'),

[ProductInstanceId] [char]

(38) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT

[DF_MacgowanTestRWISRawAtmospheric_ProductInstanceId] DEFAULT

('5abbbc86-fb2c-4703-9589-b55f763ee150'),

[SystemId] [char] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,

[RpuId] [char] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,

[SensorId] [char] (4) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[ObsDateTime] [datetime] NULL ,

[InsertDateTime] [datetime]

NOT NULL CONSTRAINT [DF_MacgowanTestRWISRawAtmospheric_InsertDateTime]

DEFAULT (getdate()),

[Temperature] [char] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

[DewPoint] [char] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,

CONSTRAINT [PK_MacgowanTestRWISRawAtmospheric] PRIMARY KEY NONCLUSTERED

(

[RecordId]

) WITH FILLFACTOR = 70 ON [PRIMARY]

) ON [PRIMARY]

GO

Monday, March 26, 2012

Many-to-Many Variation

In establishing a many-to-many relationship between two tables, a 3rd
"junction" table is created that contains at least two foreign keys.
No problem.
But - what is a recommended way to proceed to create a many-to-many
relationship between (1) one table, and (2) two other tables.
For example, say you are designing a database for a school and you are
establishing a many-to-many relationship between [Classes] and [Students]
and [Teachers].
There would obviously be a Classes table. A "junction table" could then have
foreign keys to Classes and Students. That would get us a many-to-many
relationship between Classes and Students. But we also need to show that
relationship between Classes and Teachers.
What do we do with the "junction table"? Do we add a 3rd foreign key to the
existing table? Do we create another junction table altogether?
I'd appreciate some guidance on this.
Thanks!"Smithers" <A@.B.COM> wrote in message
news:OSoQrlVlGHA.3740@.TK2MSFTNGP02.phx.gbl...
> In establishing a many-to-many relationship between two tables, a 3rd
> "junction" table is created that contains at least two foreign keys.
> No problem.
> But - what is a recommended way to proceed to create a many-to-many
> relationship between (1) one table, and (2) two other tables.
> For example, say you are designing a database for a school and you are
> establishing a many-to-many relationship between [Classes] and [Students]
> and [Teachers].
> There would obviously be a Classes table. A "junction table" could then
> have foreign keys to Classes and Students. That would get us a
> many-to-many relationship between Classes and Students. But we also need
> to show that relationship between Classes and Teachers.
> What do we do with the "junction table"? Do we add a 3rd foreign key to
> the existing table? Do we create another junction table altogether?
>
Assuming that a class has many teachers, you would use seperate junction
table. Each junction table models a different relation. One models the
"student is a member of class" relation, and the other models "class is
taught by teacher" relation.
If each class has a single teacher, then add a foreign key on the Classes
table referencing Teachers.
David|||Google up "Fifth Normal Form (5NF)"|||And then if you want to model the relationship between Teachers and Students
...
Arnie Rowland, YACE*
"To be successful, your heart must accompany your knowledge."
*Yet Another certification Exam
"David Browne" <davidbaxterbrowne no potted meat@.hotmail.com> wrote in
message news:OUsBopVlGHA.2128@.TK2MSFTNGP04.phx.gbl...
> "Smithers" <A@.B.COM> wrote in message
> news:OSoQrlVlGHA.3740@.TK2MSFTNGP02.phx.gbl...
> Assuming that a class has many teachers, you would use seperate junction
> table. Each junction table models a different relation. One models the
> "student is a member of class" relation, and the other models "class is
> taught by teacher" relation.
> If each class has a single teacher, then add a foreign key on the Classes
> table referencing Teachers.
> David|||"Arnie Rowland" <arnie@.1568.com> wrote in message
news:Ol7roDWlGHA.408@.TK2MSFTNGP03.phx.gbl...
> And then if you want to model the relationship between Teachers and
> Students ...
>
That information can be derived from the existing relations:
Select Class.Teacher, StudentClass.Student
from Class
join StudentClass
on Class.ID = StudentClass.ID
David|||I disagree.
But my disagreement is positioned on having had to work out this kind of
issue before. (I may be overlooking some simple solution you have worked
out. )
Student A has a Class B
StudentClass:
StudentClass_ID = 1, Student=A, Class=B
Teacher ZZ teaches Class B, Teacher YY also teaches Class B.
Class:
Class_ID=1,Class=B, Teacher=YY
Class_ID=2,Class=B, Teacher=ZZ
Student A's Class B is taught by Teacher ZZ
Your query will tell me that Student A has a relationship with Teacher YY
which is NOT true.
More has to be done to develop a relationship between Teachers and Students.
Arnie Rowland, YACE*
"To be successful, your heart must accompany your knowledge."
*Yet Another certification Exam
"David Browne" <davidbaxterbrowne no potted meat@.hotmail.com> wrote in
message news:elGU93WlGHA.2392@.TK2MSFTNGP04.phx.gbl...
> "Arnie Rowland" <arnie@.1568.com> wrote in message
> news:Ol7roDWlGHA.408@.TK2MSFTNGP03.phx.gbl...
>
> That information can be derived from the existing relations:
> Select Class.Teacher, StudentClass.Student
> from Class
> join StudentClass
> on Class.ID = StudentClass.ID
> David
>
>|||Arnie Rowland wrote:
> I disagree.
> More has to be done to develop a relationship between Teachers and Student
s.
> --
Correct. This problem is solved by 5th Normal Form.
David Portas, SQL Server MVP
Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.
SQL Server Books Online:
http://msdn2.microsoft.com/library/ms130214(en-US,SQL.90).aspx
--|||I don't know if I am good enough to interefere in the clash of the titans.
But Can't we have something like this?
Take it simply.. A student is associated to a particular class by a
particular teacher.
And there is no explicit teacher student relation.
The same example you had quoted.
Student A has a Class B
StudentClass:
StudentClass_ID = 1, Student=A, Class=B
Teacher ZZ teaches Class B, Teacher YY also teaches Class B.
Class:
Class_ID=1,Class=B, Teacher=YY
Class_ID=2,Class=B, Teacher=ZZ
If Student A's Class B is taught by Teacher ZZ
The the student class table should look like this
StudentClass:
StudentClass_ID = 1, Student=A, Class_ID=2
If a student is attending a session, it needs a class and a teacher.
and if such a class is happening then we should be having an entry in the
class table. Am I missing something?
--
-Omnibuzz (The SQL GC)
http://omnibuzz-sql.blogspot.com/|||Hi David (and all in the discussion),
To tell the truth, I haven't really bothered about 5NF till now.Assumed
anything above 3rd was not practical :)
But the post yesterday and the replies intrigues me. I had checked up on a
few websites and the examples that is given there doesn't convince me. Can
you direct me to a website where the explaination is given. And If I am not
able to understand, then I can discuss with reference to that.
Thanks a lot.
-Omnibuzz (The SQL GC)
http://omnibuzz-sql.blogspot.com/
"David Portas" wrote:

> Arnie Rowland wrote:
> Correct. This problem is solved by 5th Normal Form.
> --
> David Portas, SQL Server MVP
> Whenever possible please post enough code to reproduce your problem.
> Including CREATE TABLE and INSERT statements usually helps.
> State what version of SQL Server you are using and specify the content
> of any error messages.
> SQL Server Books Online:
> http://msdn2.microsoft.com/library/ms130214(en-US,SQL.90).aspx
> --
>

Many-to-many SQL Query (Failed to enable constraints)

Hi,

I have two tables (Accounts and Contacts) that have a many-to-many relationship, maintained by the AccountContactLinks table.

I would like to populate a Contacts DropDownList with all of the Contacts associated with the Account Selected in Accounts DropDownList.

Here is the (SP) SQL Query I'm trying to make work:

SELECT Contact.ContactID,
Contact.ContactLastName,
Contact.ContactFirstName,
Contact.ContactLastName+', '+ Contact.ContactFirstNameAS ContactName
FROM ContactINNERJOIN AccountContactLinksON Contact.ContactID= AccountContactLinks.ContactID
WHERE(AccountContactLinks.AccountID= @.AccountID)
ORDERBY Contact.ContactLastName
END

I keep getting the following error:

Failed to enable constraints. One or more rows contains values violating non-null, unique or foreign key constraints.

I haven't implemented any non-null, unique or foreign key constraints between any of these tables, so suspect that I've got the SQL Query wrong.

Thanks very much.

Regards

Gary

You must be trying to read that into a dataset that is set up wrong. If you are just trying to fill a dropdown, then put a dropdown control on the page, put a sqldatasource control on the page, put the SQL you have there (Or the name of the SP) as the query string, and set up the @.AccountID parameter.|||

Thanks, Motley - what you suggest is exactly what I'm doing. I've tried it both a SQL query (which runs fine in the Query Editor) and as an SP.

It's just when I test the Query in the SqlDataSource Wizard and when I try to run the page that it doesn't work.

Do you have any other ideas?

Thanks very much.

Regards

Gary

|||

It looks good to me... Well, except that you have an END statement, but I'm assuming that you cut and pasted from your SP which had a BEGIN before the select statement.

Are you sure there are no foreign key constraints? Sure looks like the AccountContactsLinks and Contacts table would be a good candidate for one.

|||

Thanks, Motley - I've found out what's wrong (by creating a new set of tables to ensure a clean start and making the same mistake, inadvertently).

The mistake that I made (twice) was to create identical records, which in a table without a primary key, introduces duplicates (i.e. creates non-unique records). I thought that I would have had to specify that records had to be unique, but now realise that, if the linking table doesn't have a key field, there is no way of identifying one record from another if the two fields are the same.

I'm concerned that SQL Server allowed this to happen and unless you or someone else has ways of preventing it from happening again, I'm going to re-introduce a Primary Key field (which someone else suggested I remove) as a safeguard.

So, I'll have to rebuild my linking table. Fortunately I've been playing around with a test database, so it won't take too long. I'll then conclude this thread with a confirmation, for the sake of people with the same problem in future.

Regards

Gary

|||I'm glad you found it. I always recommend that all tables have a primary key -- even if it's one that you create yourself via a uniqueidentifier or an identity field. In some rare cases, like in your link table, where there really is no "new" information, but just linking 2 different objects IDs to show a relationship, I'll put both fields into the primary key.

many-to-many search

Hi,
I've currently got three tables, with the second being a link table to
establish a many-to-many relationship, and I'm trying to do a full-text
search. I want it to bring up instances in the first table (only one row of
the left table per search) where the text is found, and increase the rank of
the search results, where the search string occurs in the related table.
I'm currently doing a subquery that adds the sum of the rank of the linked
tables to create a total rank (example below), but I'm concerned that since
the two full-text queries aren't linked, the two ranks aren't relevant to
each other.
Has anyone else found a good/better way to do this?
Regards,
Dunc
--/ snip /--
SELECT * FROM (
SELECT VenueDetailID, VenueName, Addr1, Addr3, Addr4,
ISNULL(B.RANK, 0) + ISNULL(
(SELECT SUM(Rank)
FROM VenueExtras Y
INNER JOIN LinkExtrasVenue
ON Y.VenueExtrasID = LinkExtrasVenue.VenueExtrasID
AND LinkExtrasVenue.VenueID = A.VenueDetailsID
INNER JOIN CONTAINSTABLE(VenueExtras, ExtraName, 'ISABOUT ("cocktails"
WEIGHT(0.1))') AS Z
ON Y.VenueExtrasID = Z.[Key]), 0)
AS Rank
FROM VenueDetail AS A
LEFT JOIN CONTAINSTABLE(VenueDetail , VenueName, 'ISABOUT ("cocktails"
WEIGHT(0.1))') AS B
ON A.VenueDetailID = B.[Key]
WHERE A.Status > 0
) SubQuery
ORDER BY Rank DESC, VenueName
can you post the schema of all related tables?
Is it possible to consolidate VenueExtras and VenueDetails into a single
table?
Hilary Cotter
Looking for a book on SQL Server replication?
http://www.nwsu.com/0974973602.html
"Duncan Welch" <dunc@.ntpcl.f9.co.uk> wrote in message
news:esp%234lheEHA.3928@.TK2MSFTNGP11.phx.gbl...
> Hi,
> I've currently got three tables, with the second being a link table to
> establish a many-to-many relationship, and I'm trying to do a full-text
> search. I want it to bring up instances in the first table (only one row
of
> the left table per search) where the text is found, and increase the rank
of
> the search results, where the search string occurs in the related table.
> I'm currently doing a subquery that adds the sum of the rank of the linked
> tables to create a total rank (example below), but I'm concerned that
since
> the two full-text queries aren't linked, the two ranks aren't relevant to
> each other.
> Has anyone else found a good/better way to do this?
> Regards,
> Dunc
> --/ snip /--
> SELECT * FROM (
> SELECT VenueDetailID, VenueName, Addr1, Addr3, Addr4,
> ISNULL(B.RANK, 0) + ISNULL(
> (SELECT SUM(Rank)
> FROM VenueExtras Y
> INNER JOIN LinkExtrasVenue
> ON Y.VenueExtrasID = LinkExtrasVenue.VenueExtrasID
> AND LinkExtrasVenue.VenueID = A.VenueDetailsID
> INNER JOIN CONTAINSTABLE(VenueExtras, ExtraName, 'ISABOUT ("cocktails"
> WEIGHT(0.1))') AS Z
> ON Y.VenueExtrasID = Z.[Key]), 0)
> AS Rank
> FROM VenueDetail AS A
> LEFT JOIN CONTAINSTABLE(VenueDetail , VenueName, 'ISABOUT ("cocktails"
> WEIGHT(0.1))') AS B
> ON A.VenueDetailID = B.[Key]
> WHERE A.Status > 0
> ) SubQuery
> ORDER BY Rank DESC, VenueName
>
|||In the name of keeping things a little secure, I've changed the names to
protect the innocent (table and field names, that is) on the example. I've
actually normalised them out of being one table (it used to contain a bitmap
field that related to each extra (which used to be stored in a global
array)) so I can search on them with a ranking; also there may eventually be
as many as 100 different extras.
In the example, I've simplified the scheme to the following:
Table: VenueDetails
VenueDetailsID
VenueName
Addr1
Addr2
Addr3
Addr4
Description
Table: LinkExtrasVenue
VenueID
VenueExtrasID
Table: VenueExtras
VenueExtrasID
ExtraName
A venue listing may have a name of "Bob's Cocktail Palace", which may have
extras of "Cocktails" and "Cocktails recommended". This needs to be ranked
above "Bill's Bar" which has an extra of "Cocktails", which in turn needs to
be ranked higher than "Brian's bar" which is situated on "15 Cocktail St"
Confused yet? I am!
At the risk of looking like I'm having a free plug, so you can see how it
works - check out:
http://www.fluidfoundation.com/venue...sp?BarRef=1405 - you'll notice
this one has the two cocktails flags set, whereas:
http://www.fluidfoundation.com/venue...sp?BarRef=2820 doesn't, so
*should* come second in the rankings when you search on "Cocktails". But
doesn't.
Dunc
"Hilary Cotter" <hilaryk@.att.net> wrote in message
news:OOec7vheEHA.2812@.tk2msftngp13.phx.gbl...[vbcol=seagreen]
> can you post the schema of all related tables?
> Is it possible to consolidate VenueExtras and VenueDetails into a single
> table?
> --
> Hilary Cotter
> Looking for a book on SQL Server replication?
> http://www.nwsu.com/0974973602.html
>
> "Duncan Welch" <dunc@.ntpcl.f9.co.uk> wrote in message
> news:esp%234lheEHA.3928@.TK2MSFTNGP11.phx.gbl...
row[vbcol=seagreen]
> of
rank[vbcol=seagreen]
> of
linked[vbcol=seagreen]
> since
to
>

Many-to-Many Relationship?

I cannot get my head round how to create a database where two of the tables
require a many-to-many relationship.
I posted on another group and was advised to make a third joining table, but
I don't really understand how this works.
Can anyone help?
Basically I have a table of Individuals, and a table of Businesses. A
business can be related to many individuals, and an individual to many
businesses.
ThanksKeith
Did you read the link which David posted here?
"Keith" <@..> wrote in message news:esRuNtWFEHA.2976@.TK2MSFTNGP10.phx.gbl...
> I cannot get my head round how to create a database where two of the
tables
> require a many-to-many relationship.
> I posted on another group and was advised to make a third joining table,
but
> I don't really understand how this works.
> Can anyone help?
> Basically I have a table of Individuals, and a table of Businesses. A
> business can be related to many individuals, and an individual to many
> businesses.
> Thanks
>|||Keith wrote:
> I cannot get my head round how to create a database where two of the
> tables require a many-to-many relationship.
> I posted on another group and was advised to make a third joining
> table, but I don't really understand how this works.
> Can anyone help?
> Basically I have a table of Individuals, and a table of Businesses. A
> business can be related to many individuals, and an individual to many
> businesses.
Yes, a junction table is needed. From BOL - it is a table that establishes a
relationship between other tables. The junction table contains foreign keys
referencing the tables that form the relationship. For example, an
OrderParts junction table can show what parts shipped with each order by
having foreign keys to an Orders table and a Parts table. In your case:
Business
--
PK ID_Business int
(...)
Individuals
--
PK ID_Individual int
(...)
BusinessIndividuals
--
PK ID_Business int
PK ID_Individual int
Business.ID_Business -- BusinessIndividuals.ID_Business
Individuals.ID_Individual -- BusinessIndividuals.ID_Individual
sincerely,
--
Sebastian K. Zaklada
Skilled Software
http://www.skilledsoftware.com
This posting is provided "AS IS" with no warranties, and confers no rights.|||Hi Keith
Many to Many relationships takes a bit of effort to get
your head around.
Anyways here is my take on it.
You have a table called student, and a table called class.
A Student can take may classes, and a class can have many
students.
So in the Student Table you would have something like
Keith SQL Beginner Course
Keith SQL Intermediate Course
Julie SQL Beginner Course
Matt ASP Beginner Course
However in the Class table you would have
SQL Beginner Course Keith
SQL Beginner Course Julie
SQL Intermediate Course Keith
ASP Beginner Course Matt
Now this is bad because you are copying data (third normal
form), in the Student table it would be better to have
each student entered once, and in classes, its better to
enter a classes only once.
Here is where the third table comes in.
So out Student Table we would have
Keith
Julie
Matt
and in the Classes table we would have
SQL Beginner Course
SQL Intermediate Course
ASP Beginner Course
Now you would have a link table
Keith SQL Beginner Course
Keith SQL Intermediate Course
Julie SQL Beginner Course
Matt ASP Beginner Course
Anyway the example is a very simple one. There are tons of
examples out on the net.
Enjoy
J

>--Original Message--
>Keith
>Did you read the link which David posted here?
>"Keith" <@..> wrote in message
news:esRuNtWFEHA.2976@.TK2MSFTNGP10.phx.gbl...
where two of the
>tables
third joining table,
>but
Businesses. A
individual to many
>
>.
>|||Thanks everyone
I have just got my head round this now (or at least have got it working -
still not sure I understand it :-))
"Keith" <@..> wrote in message news:esRuNtWFEHA.2976@.TK2MSFTNGP10.phx.gbl...
> I cannot get my head round how to create a database where two of the
tables
> require a many-to-many relationship.
> I posted on another group and was advised to make a third joining table,
but
> I don't really understand how this works.
> Can anyone help?
> Basically I have a table of Individuals, and a table of Businesses. A
> business can be related to many individuals, and an individual to many
> businesses.
> Thanks
>

Many-to-Many relationship with Time dimension?

Is it possible to use a Time dimension as the intermediate dimension in a many-to-many relationship? So far, I have not been able to make it work. When I attempt to setup the relationship, I get a warning on the Define Relationship window that says:

This relationship cannot be defined because no intermediate measure group or dimension table exists.

However, the intermediate measure group and dimension tables do exist. The New Cube... wizard picks up the tables but creates all the relationships as Regular, in effect I have two separate measure groups. Do I have to do something special to define a measure group as intermediate?

The business problem I'm trying to model here is special time periods that can overlap - think college and university semesters. I can have a semester where any given day (the granularity of my time dimension) can exist in multiple semesters. So I am trying to create a many-to-many relationship from my "semesters" to an intermediate mesaure group to time dimension to real measure group.

Any help or guidance is much appreciated!

Hello. Check for intermediate dimensions in BooksOnLine. This is what I think you are trying do do. Many-to-many dimensions are between a normal fact table and a many-to-many artificial fact table with the many-to-many relation with a dimension table.

A good example is an account that is shared between two persons. You have the single account in the dimension and the many-to-many relation between the persons and the account in the artificial fact table.

Here is a link to a Blog about the new dimension types in SSAS2005: http://blogs.conchango.com/christianwade/archive/2005/04/07/1255.aspx

An intermediate dimension is when you do not have a direct relation between a fact table and a dimension. Normally you have a direct relation.

The use for this type is more limited since that you can always enter more dimenion keys into a fact table.

I would think about two new attributes in the time dimension like:

-CollegeSemesterDayFlag

-UniversitySemesterDayFlag

HTH

Thomas Ivarsson

|||

Thanks for the response Thomas. I do want a many-to-many dimension, I just didn't explain my business problem clearly. I have potentially multiple, overlapping, arbitrary time spans (again, think college/university semesters), where any given day can exist in multiple semesters. This is very similar to the example you gave above with the accounts shared between multiple people. My problem is that I could have a semester called FALL from Sep1-Dec31 and a semester called FALL_SPECIAL Oct1-Oct31, where the date range Oct1-Oct31 falls into two semesters. Also, from year to year, there will be different semesters - some years won't have a FALL_SPECIAL, but have a WINTER_SPECIAL, etc.

Anyway, I solved my problem and it was because the New Cube... wizard didn't find all the relationships. I am using my time dimension as the intermediate dimension and it is also acting as a role playing dimension. The New Cube... wizard didn't pick up all those relationships, so I had to manually setup to the many-to-many relationship for all five of my role playing time dimensions, only then it recognized the second fact table as an intermediate fact table. I also had to delete a time dimension that showed up in the Dimension Usage tab that didn't belong but the New Cube... wizard put in there.

I haven't explored all the data to make sure it's aggregating correctly, but it appears to be doing what I want and I'm quite impressed I might add! I just need to verify that the ParallelPeriod() and Cousin() functions behave properly.

|||

Great that you have solved the problem.

I think that this is no more than standard many-to-many modelling.

You have several colleges and universities on top with their own semester schedule and this means that it will be a many-to many relation with the time dimension.

This means an education institution-semester dimension on top of the time dimension.

Regards

Thomas

sql

Many-to-many Relationship Issue/Question

Hello All,

Here's what I got so far:

- Employee fact table with 10 dimensions connected to it

- A Factless Bonus table and the Employee fact table are connected through a common dimension of Time.

- The Factless Bonus table connects to a Bonus Dimension

- added a many-to-many relationship with the Bonus Dimension to the Employee fact table

How can I slice and dice by both the other 10 dimensions and the Bonus Dimension?

Thank you.

-Gumbatman

"How can I slice and dice by both the other 10 dimensions and the Bonus Dimension?" - but aren't you already able to slice and dice the measures from the Employee fact table this way? If not, could you explain what the problem is in more detail? It seems strange that Bonus should only be a function of time, and not of any other dimension; but maybe that's in the nature of your problem.|||

Deepak,

I apologize for not expressing this as well as I could. I just used the Time dimension as an example. Sorry about that...

Here's the situation:

I have a fact table that has one row per employee, per month. I now need to add bonuses that were received by the employees. The issue is that employees can received more than one bonus per month and sometimes those bonuses can be the same type.

So the question is: How can I have multiple bonuses for an employee in a single month when they only have one row in that month?

When I tried connecting the Fact tables, I didn't know what made the most logical sense to have as that intermediate dimension. When I tried using Time, I could get that they got a bonus and when they got it, but I could not do any additional slicing across other dimensions (the 10 I mentioned) that the Employee Fact table is connected to.

My results would be that Employee John Doe got five bonuses this month, but it would not show that he was in the Southeast. It would place those bonuses only in the Midatlantic area.

Thank you so much for the help. This has been driving me crazy.

-Gumbatman

p.s. Another thing I need to do is show which employees when to which school. Again, employees may have attended more than one school.

|||So there are apparently 2 fact tables/measure groups here: EmployeeMonthly and BonusMonthly, with the latter having an associated "BonusType" dimension. But are the other 10 dimensions all directly related to EmployeeMonthly, or are some referenced via a separate "Employee" dimension (ie. each employee has a single associated member)? In either case, these dimensions would have referenced relationships to the BonusMonthly measure group, either via the Employee or EmployeeMonthly fact dimension. The only obvious many-to-many relation is between the BonusType dimension and the EmployeeMonthly measure group, via the BonusMonthly measure group (I'm assuming that EmployeeMonthly has a composite key like {Employee, Month}, which is a foreign key in BonusMonthly).|||

Deepak,

I couldn't get the quoting to work, but here are my answers:

So there are apparently 2 fact tables/measure groups here: EmployeeMonthly and BonusMonthly, with the latter having an associated "BonusType" dimension.

- Yes

But are the other 10 dimensions all directly related to EmployeeMonthly, or are some referenced via a separate "Employee" dimension (ie. each employee has a single associated member)?

- The other 10 dimensions all directly related to EmployeeMonthly,

In either case, these dimensions would have referenced relationships to the BonusMonthly measure group, either via the Employee or EmployeeMonthly fact dimension.

- I haven't tried that yet, but I will. I think that is one of the points I am missing.

The only obvious many-to-many relation is between the BonusType dimension and the EmployeeMonthly measure group, via the BonusMonthly measure group (I'm assuming that EmployeeMonthly has a composite key like {Employee, Month}, which is a foreign key in BonusMonthly).

- That makes perfect sense, but I am still confused on the exact relationship between EmployeeMonthly and BonusType. How do they connect to each other? Is that with a composite key or with BonusMonthly? Or is BonusMontly a table with the composite key?

When you are referring to a composite key, do you mean selecting the EmployeeKey, BonusKey, Date, etc. and make that a key? Or concatenating those keys into a single field for the row, which is now a Primary Key?

The way I picture this is:

EmployeeMonthly Table

Employee Monthly Key Employee Key Date Key Bonus Composite Key 1 1 20061001 0 2 2 20061001 2_20061001 3 1 20061101 0 4 2 20061101 0

BonusMonthly Table

Employee Key DateKey Bonus Key Bonus Composite Key 2 20061001 1 2_20061001 2 20061001 1 2_20061001 2 20061001 2 2_20061001

Here Employee #2 got three bonuses on 10/1/2006. Two of the bonuses were the same type and that is what confuses me about the composite keys, don't I need a Primary key in BonusMontly?

Also, I may be thinking in terms of a relational database, but when I connect EmployeeMonthly and BonusMonthly (in the setup above) I would expect three rows of duplicated data. Is that correct?

Thank you so much for your help with this.

-Gumbatman

|||Based on the sample data, EmployeeMonthlyKey could be added as a Foreign Key to BonusMonthly, allowing the EmployeeMonthly fact dimension to directly relate to BonusMonthly measure group. Then BonusType could have a many-to-many relation to EmployeeMonthly measure group, with BonusMonthly being the intermediate measure group. You might not need a primary key in BonusMonthly, unless you're also setting it up as a fact dimension (eg: for drillthrough).|||

Deepak,

I got this to work, almost...

The problem I am still having is with the Dimensions that are related only to the EmployeeMonthly fact table.

For example,

- EmployeeMonthy is related to BonusType dimension through BonusMonthly measure group.

- EmployeeMonthy also has dimensions directly related to it, such as a Geographic dimension, JobLevel dimension, Product dimension, etc.

When I want to see Bonus data by Geographic Area, I am getting strange results. The numbers are correct, but the bonuses are not properly breaking down by Geographic Area. It appears that it is only taking the first member of the Geographic dimension.

I tried setting them (BonusType and Geographic) as many-to-many, but that didn't work.

How is it supposed to work? Is there a way around this? I am thinking of just duplicating all the dimensions on the EmployeeMonthly onto the BonusMonthly fact table.

I really appreciate the time and energy you've put into helping me with this.

-Gumbatman

|||"The problem I am still having is with the Dimensions that are related only to the EmployeeMonthly fact table" - as I mentioned earlier, you could configure these dimensions with referenced (not many-to-many) relationships to the BonusMonthly measure group, via the EmployeeMonthly fact dimension (which you should have already configured as directly related to the BonusMonthly measure group). These referenced relationships could be materialized, for better performance. Or you could, as you suggest, directly relate these dimensions to the BonusMonthly measure group, but this might involve adding a join to the fact table named query.|||

Deepak,

Thank you so much, I finally got it to work!

I didn't really catch it when you spoke about referenced dimensions. Plus, my lack of understanding made me gloss over it.

I really appreciate all the time and effort you put into helping me with this. I would never of have gotten to the solution without your expertise.

-Gumbatman

many-to-many parent-child relationship in the dimension hierarchy

This novice would like your assistance to solve a problem. The goal is to build a Data mart for use in a cube. The cube would have a Service Fact related to the Dimension of Personnel and Assets. The Measures would be:

Provision of Assets by Departments

Availability of Assets by Departments or Service

Volume of Support Calls by Departments

The model has one major problem: a many-to-many parent-child relationship in the hierarchy of the Asset Dimension. The hierarchy within the Dimension is

Bundle

Service

Assets

And the many-to-many relationship resides between Assets & Service.I wish to know how best to handle this situation; create a bridge table or create a Service Dimension. All advice is welcomed.

What is the business process you are modeling in your fact table? The description of the measures is a little confusing to me.

Regarding the many-to-many relationship, you are saying that the fact table has a relationship to an asset, the asset belongs to multiple services, and a service belongs to a single bundle. Is that correct?

Also, what is the relationship between the fact and the service? Does a single fact record associate to a single service or does it associated to multiple services through the asset?

Thanks,
Bryan

|||The main objective is to create a cube on IT Support for performance reporting against SLAs, with a secondary objective being to expose the use of IT within the organisation. The high level categories of measures are: provisioning, availability, volume, and minutes. These would translate into measurement exposing the aggregated number of Assets provisioned; the percentage an Asset was available; the aggregated number of support calls received for an Asset; the minutes taken to close a support call on an Assest. Basically, sliced, diced and rolled up and down by organisation section, business unit, IT bundle and service. This is datamart design based on this information:

Code Snippet

Assets Dim -> Support Fact <- Personnel Dim
AssetID AssetID PersonnelID
Class PersonnelID Job
Service %Available Business Unit
Bundle Provisioned Assets Section
Call volume
Call minutes

The Dimensions have been model to the lowest level of granularity. The Personnel Dimension offers no problems with the hierarchy; a staff member only belongs to one job, business unit & section. This is not the case for Assets. All Assets are assigned to a member of staff. An Asset is a member of a class --mobile, pc, server,...--, one or many services and those services are member of one bundle.

"Regarding the many-to-many relationship, you are saying that the fact table has a relationship to an asset, the asset belongs to multiple services, and a service belongs to a single bundle. Is that correct?"

Yes. The IT Business Unit offers 5 bundles of services. Each bundle is comprise of mutually exclusive services. An example would be the End User Computing Bundle comprising of Desk Support, Printing & Fax, etc.

"Also, what is the relationship between the fact and the service? Does a single fact record associate to a single service or does it associated to multiple services through the asset?"

One or multiple through the asset. Each Asset is tired to at lest one service. Assets such as servers offer more than one service.

I appreciate your response and am happy to supply additional information.
|||

According to Kimball methodology, a fact table should represent a single business process. So in this data mart, you would have a fact table for the handling of service tickets, another one for provisioning, another one for asset uptime/availability, and so on and so on. You might bring all this data together in a report using conformed dimensions between the fact tables. I'd recommend taking a look into that. It will make your maintanance of the data much, much easier. (You can easily tie all this data together in your olap cube so your users won't have to jump between fact tables aka measure groups.)

When you do that, I think you will find that some facts relate directly to assets while others relate directly to the services.

Still, you will have assets providing services and need to model that relationship. I'd recommend building a service group table that ties together the services being offered. Then associate an asset with a service group. Here's a rough example:

Asset (AssetID, ServiceGroupID, ..., StartDate, EndDate)

ServiceGroup (ServiceGroupID, ....)

ServiceGroupServiceJunction (ServiceGroupID, ServiceID, ....)

Service (ServiceID, ....)

So, if you had a fact associated with an asset, you would be able to identify what services are provided by that asset. If you are working with Asset as a Type 2 slowly changing dimension, there would be different records for an asset in the Asset table based on the ServiceGroups it was associated with across time.

If you have a copy of "The Microsoft Data Warehouse Toolkit", this is covered on page 60. (I think this is covered in "The Data Warehouse Toolkit" as well but someone has borrowed by copy.)

Hope that helps,
Bryan

|||Bryan,

Thanks for your suggestions and insight. I will have a read of the books mentioned and most likely return with a few questions...hopefully your generosity will continue to provide answers.

Ian
|||

Assuming that you're using AS 2005, the many-many relationship between Assets and Services could be modelled, if separate Asset and Service dimensions are set up. There is 1 measure that isn't just additive, and hence may need further fields in the fact table: "the percentage an Asset was available". Generally, availability is a ratio like available to total time. Even in the simplest scenario, the numerator and denominator would be separately summed (say across Assets in this case), then their ratio taken. So, if the fact table has either "%Available" or "AvailableTime", and "TotalTime", the aggregate "%Available" could be computed.

The schema for AS 2005 could then be something like:

PersonnelDim SupportFact AssetDim Asset<->ServiceBridge ServiceDim

AssetID --> AssetID <-- AssetID

PersonnelID <-- PersonnelID Asset ServiceID --> ServiceID

Job AvailTime Class Service

Business Unit TotalTime Bundle

Section Provisioned

Call Volume

Call Minutes

There would be a Measure Group on SupportFact, with "sum" measures: AvailTime, TotalTime, Provisioned, Call Volume, Call Minutes.

["%Available] could then be defined as: AvailTime / TotalTime.

The Personnel and Asset dimensions would have a regular relation to the SupportFact Measure Group.

An intermediate Measure Group is then defined on the Asset<->ServiceBridge table, to which Asset and Service dimensions are related.

This would allow the Service dimension to have a many-many relation to the SupportFact Measure Group, via this intermediate MG.

Friday, March 23, 2012

Many to one relationship

Hello

I have need to write a query that I can pass in a bunch of filter criteria, and return 1 result...it's just ALL of the criteria must be matched and a row returned:

example:

Transaction table: id, reference

attribute table: attributeid, attribute

transactionAttribute: attributeid, transactionid

Example dat

Attribute table contains: 1 Red, 2 Blue, 3 Green

Transaction table contains: 1 one, 2 two, 3 three

transactionAttribute contains: (1,1), (1,2), (1,3), (2,3), (3,1)

If I pass in Red, Blue, Green - I need to be returned "one" only

If I pass in Red - I need to be returned "three" only

If I pass in Red, Green - nothing should be returned as it doesn't EXACTLY match the filter criteria

If anyone's able to help that would be wonderful!

Thanks, Paul

Hi Paul,

To get the result, you cannot pass the Attribute strings directly, you have to seperate them with commas. Each one is quoted with single quotes.

Here is an example for

SELECT * FROM TransactionAttribute
LEFT OUTER JOIN AttributeTable ON TransactionAttribute.AttributeId = AttributeTable.AttributeId
LEFT OUTER JOIN TransactionTable ON TransactionAttribute.TransactionId=TransactionTable.TransactionID
WHERE Attribute IN ('Red', 'Green')

HTH.

sql

Many to many relationships

Hi,

I have a many-to-many relationship scenario and I had used a group dimension instead of the bridge table concept.

I had referred "Data Warehouse Lifecycle Toolkit" by Kimball and others.

For ex:
An Athlete belonging to multiple athletic teams and with the possiblity of changing every year.

So I had created an Athlete Team dimension, with a group key and the team code.

Athelete Group Key,
Athelete Team Code,
Athelete Team Name

with Athlete Group Key and Athlete Team Code as the key for the table.

And in the fact/measure group, referring to the Group Key.

Now, in SSAS, I had created the Athlete Team dimension with Group Key as the key atrribute and others as dimension attributeS.


***********************
Athlete dimension table
--

Group Key, Athlete Code, Athlete Name,
1 , FTB , Football
1 , TEN , Tennis
2 , TEN , Tennis
2 , VOL , Volleyball

Fact/Measure group

Athlete ID, Year, Group Key
123 , 2001, 1
234 , 2001, 2

************************

When processed and browsed the cube, for the number of students for each type of team, the result is considering only the first team for the count (it is ordered alphabetically).

In the sample data example above, the count of athletes for team Football, Tennis and Volleyball are 1, 2 and 1 respectively.

But in SSAS, the count of athletes for the team Football, Tennis and Volleyball are 1, 1 and 0 respectively.

For the same requirement, the SQL query on the SQLDB, is fetching me the correct result, but this is required for adhoc reporting as well and hence have to be done using the cube itself.

Comments on this would be really helpful.

Thanks,
Vivek C.

Vivek,

I might just be getting stuck on the example, but this sounds like a Type 2 changing dimension and not a many-to-many scenario.

So, you have this Athlete dimension. It's primary key is AthleteID and contains a reference to the TeamID. Here is the structure of the table:

create table Athlete (

AthleteID int not null identity(1,1),

Name varchar(200) not null,

TeamID int not null,

RowStartDate datetime not null default (getdate()),

RowEndDate datetime null,

IsRowCurrent bit not null default (1)

)

alter table Athlete add

constraint PK_Athlete primary key (athleteid),

constraint AK_Athlete unique (name, rowstartdate),

constraint FK_Athlete_TeamID foreign key (teamid) references Team (TeamID)

create table Team (

TeamID int not null identity(1,1),

Name varchar(200) not null

)

alter table Team add

constraint PK_Team primary key (teamid),

constraint AK_Team unique (teamid)

Every time an athlete changes a team, a new record is created for the record. The previous record gets end dated and the IsRowCurrent flag gets properly set. In your cube, you can use these two tables in a single dimension or do two dimensions and create a referenced relationship.

If an athlete could belong to multiple teams simultaneously, you would then have a many-to-many relationship. In this scenario, you would have Athlete and Team dimension tables. The Athlete table would not have a reference to the Team dimension table. Instead, you would have a AthleteTeam table which contains a reference to the Athlete dimension table and another to the Team dimension table. This is your bridge table concept.

Let's say a single record in the fact table pointed to multiple athletes, such as athletes involved in a play (think baseball). This would be the group table you mentioned. You would have an Athlete table like described above that points to Team. You would build a table that assigns a single group ID to the list of players involved, and a Group table that represents that list. The fact table would point to the Group table.

create table AthleteGroup (

AthleteGroupID int not null identity(1,1),

NumberOfAthletes int not null

)

alter table AthleteGroup add constraint PK_AthleteGroup primary key (athletegroupid)

create table AthleteGroupAthlete (

AthleteGroupID int not null,

AthleteID int not null

)

alter table AthleteGroupAthlete add

constraint PK_AthleteGroupAthlete primary key (AthleteGroupID, AthleteID),

constraint FK_AthleteGroupAthlete_AthleteGroupID foreign key (athletegroupid) references AthleteGroup (AthleteGroupID),

constraint FK_AthleteGroupAthlete_AthleteID foreign key (athleteid) references Athlete (AthleteID)

The AthleteGroupAthlete table would then be used to create a measure group with a single measure (using a COUNT aggregation). This becomes the intermediate measure group in the many-to-many relationship.

Good luck,
Bryan

|||

Hi Bryan,

Thanks for the reply.

My requirement is for an athlete belonging to multiple teams simultaneously. And the way you have explained in the second part, would have been the right way to move ahead.

But currently, the way it is implemented is as explained my first post. Is there a way to make it work with some settings in Analysis Services Solution? As said earlier the concept of the grouping works, when we work on the relational database based data warehouse.

Thanks,

Vivek C.

|||

Sorry for not replying sooner. For some reason I'm not getting alerts regularly.

Regarding the Athelete dimension, I'm afraid I don't see a way to implement it the way you describe. Is changing the model an option for you?

Thanks,
Bryan

|||

Changing the data model would be difficult, as we have already done with the ETL work and certain set of reports.

Anyway thanks for the inputs, let me see whether I can talk others into changing the model.

Thanks,

Vivek

|||The simplest representation seems to be a fact table reperesenting membership in a team and then a Team dimension, an Athlete dimension, and a Time dimension (with a granularity of year). Then the fact table simply contains a row for each team an athlete is on for each year the athelete is on that team. Then your measure group can contain a single measure that is a count of rows which you can filter based on any combination of team, athlete, or year. If I recall correctly, Kimball calls this type of design a "factless fact table".|||

Hi Matt,

Thanks for the inputs. The reason for not implementing using the factless fact (this was our first option), was data explosion.

Consider the case where the Athlete can belong to different team simultaneously and this changing every quarter. In this case the number of records would keep increasing periodically (quarterly). So we thought we would go the grouping of athlete teams.

Though the grouping option works with the data warehouse, we are not able to get it work properly using SSAS.

My guess is that SSAS handles many to many relationships using the factless fact table.

Thanks,

Vivek

|||

You'd be surprised at how many records you can handle if you keep them smalll by using int or smallint for your foreign keys. Assuming 3 int foreign keys, each row would cost you 3*4=12 Bytes without any indexes and SSAS doesn't need indexes. 1000 athlethes on an average of 4 teams over 100 years at the quarter level granularity would need 1000*4*100*4=19,2000,000 rows. This sounds like a lot, but at 12 bytes per row this is only 18.3MB which is tiny.

I must admint, I don't fully understand the design you originally described. It sounds like two dimensions and one fact table with no many-to-many relationships in AS terms (that is, both dimensions are regular dimensions for the measure group.) Based on this, I suspect the problem you are currently seeing is caused by dimension keys not being unique for the Athlete Team table since Team Code will occur multiple times in the Ahtlete Team table. I think what you may want to do in this design is to break out Group Key from the Ahtlete Team table and create a GroupToTeam table contain Group Key and Team code. This table would be a fact table in AS which would then be used to create a many-to-many relationship from your other Fact table to the Athlete Team table.

|||

Matt,

The way you have explanied of breaking the Group Key from the Athelete Team table/dimension is the best thing to do.

Anyway, we have gone ahead and changed our data model to the way exactly SSAS handles, viz. by factless fact tables.

Thanks for the inputs.

Vivek

Many to many relationships

Hi,

I have a many-to-many relationship scenario and I had used a group dimension instead of the bridge table concept.

I had referred "Data Warehouse Lifecycle Toolkit" by Kimball and others.

For ex:
An Athlete belonging to multiple athletic teams and with the possiblity of changing every year.

So I had created an Athlete Team dimension, with a group key and the team code.

Athelete Group Key,
Athelete Team Code,
Athelete Team Name

with Athlete Group Key and Athlete Team Code as the key for the table.

And in the fact/measure group, referring to the Group Key.

Now, in SSAS, I had created the Athlete Team dimension with Group Key as the key atrribute and others as dimension attributeS.


***********************
Athlete dimension table
--

Group Key, Athlete Code, Athlete Name,
1 , FTB , Football
1 , TEN , Tennis
2 , TEN , Tennis
2 , VOL , Volleyball

Fact/Measure group

Athlete ID, Year, Group Key
123 , 2001, 1
234 , 2001, 2

************************

When processed and browsed the cube, for the number of students for each type of team, the result is considering only the first team for the count (it is ordered alphabetically).

In the sample data example above, the count of athletes for team Football, Tennis and Volleyball are 1, 2 and 1 respectively.

But in SSAS, the count of athletes for the team Football, Tennis and Volleyball are 1, 1 and 0 respectively.

For the same requirement, the SQL query on the SQLDB, is fetching me the correct result, but this is required for adhoc reporting as well and hence have to be done using the cube itself.

Comments on this would be really helpful.

Thanks,
Vivek C.

Vivek,

I might just be getting stuck on the example, but this sounds like a Type 2 changing dimension and not a many-to-many scenario.

So, you have this Athlete dimension. It's primary key is AthleteID and contains a reference to the TeamID. Here is the structure of the table:

create table Athlete (

AthleteID int not null identity(1,1),

Name varchar(200) not null,

TeamID int not null,

RowStartDate datetime not null default (getdate()),

RowEndDate datetime null,

IsRowCurrent bit not null default (1)

)

alter table Athlete add

constraint PK_Athlete primary key (athleteid),

constraint AK_Athlete unique (name, rowstartdate),

constraint FK_Athlete_TeamID foreign key (teamid) references Team (TeamID)

create table Team (

TeamID int not null identity(1,1),

Name varchar(200) not null

)

alter table Team add

constraint PK_Team primary key (teamid),

constraint AK_Team unique (teamid)

Every time an athlete changes a team, a new record is created for the record. The previous record gets end dated and the IsRowCurrent flag gets properly set. In your cube, you can use these two tables in a single dimension or do two dimensions and create a referenced relationship.

If an athlete could belong to multiple teams simultaneously, you would then have a many-to-many relationship. In this scenario, you would have Athlete and Team dimension tables. The Athlete table would not have a reference to the Team dimension table. Instead, you would have a AthleteTeam table which contains a reference to the Athlete dimension table and another to the Team dimension table. This is your bridge table concept.

Let's say a single record in the fact table pointed to multiple athletes, such as athletes involved in a play (think baseball). This would be the group table you mentioned. You would have an Athlete table like described above that points to Team. You would build a table that assigns a single group ID to the list of players involved, and a Group table that represents that list. The fact table would point to the Group table.

create table AthleteGroup (

AthleteGroupID int not null identity(1,1),

NumberOfAthletes int not null

)

alter table AthleteGroup add constraint PK_AthleteGroup primary key (athletegroupid)

create table AthleteGroupAthlete (

AthleteGroupID int not null,

AthleteID int not null

)

alter table AthleteGroupAthlete add

constraint PK_AthleteGroupAthlete primary key (AthleteGroupID, AthleteID),

constraint FK_AthleteGroupAthlete_AthleteGroupID foreign key (athletegroupid) references AthleteGroup (AthleteGroupID),

constraint FK_AthleteGroupAthlete_AthleteID foreign key (athleteid) references Athlete (AthleteID)

The AthleteGroupAthlete table would then be used to create a measure group with a single measure (using a COUNT aggregation). This becomes the intermediate measure group in the many-to-many relationship.

Good luck,
Bryan

|||

Hi Bryan,

Thanks for the reply.

My requirement is for an athlete belonging to multiple teams simultaneously. And the way you have explained in the second part, would have been the right way to move ahead.

But currently, the way it is implemented is as explained my first post. Is there a way to make it work with some settings in Analysis Services Solution? As said earlier the concept of the grouping works, when we work on the relational database based data warehouse.

Thanks,

Vivek C.

|||

Sorry for not replying sooner. For some reason I'm not getting alerts regularly.

Regarding the Athelete dimension, I'm afraid I don't see a way to implement it the way you describe. Is changing the model an option for you?

Thanks,
Bryan

|||

Changing the data model would be difficult, as we have already done with the ETL work and certain set of reports.

Anyway thanks for the inputs, let me see whether I can talk others into changing the model.

Thanks,

Vivek

|||The simplest representation seems to be a fact table reperesenting membership in a team and then a Team dimension, an Athlete dimension, and a Time dimension (with a granularity of year). Then the fact table simply contains a row for each team an athlete is on for each year the athelete is on that team. Then your measure group can contain a single measure that is a count of rows which you can filter based on any combination of team, athlete, or year. If I recall correctly, Kimball calls this type of design a "factless fact table".|||

Hi Matt,

Thanks for the inputs. The reason for not implementing using the factless fact (this was our first option), was data explosion.

Consider the case where the Athlete can belong to different team simultaneously and this changing every quarter. In this case the number of records would keep increasing periodically (quarterly). So we thought we would go the grouping of athlete teams.

Though the grouping option works with the data warehouse, we are not able to get it work properly using SSAS.

My guess is that SSAS handles many to many relationships using the factless fact table.

Thanks,

Vivek

|||

You'd be surprised at how many records you can handle if you keep them smalll by using int or smallint for your foreign keys. Assuming 3 int foreign keys, each row would cost you 3*4=12 Bytes without any indexes and SSAS doesn't need indexes. 1000 athlethes on an average of 4 teams over 100 years at the quarter level granularity would need 1000*4*100*4=19,2000,000 rows. This sounds like a lot, but at 12 bytes per row this is only 18.3MB which is tiny.

I must admint, I don't fully understand the design you originally described. It sounds like two dimensions and one fact table with no many-to-many relationships in AS terms (that is, both dimensions are regular dimensions for the measure group.) Based on this, I suspect the problem you are currently seeing is caused by dimension keys not being unique for the Athlete Team table since Team Code will occur multiple times in the Ahtlete Team table. I think what you may want to do in this design is to break out Group Key from the Ahtlete Team table and create a GroupToTeam table contain Group Key and Team code. This table would be a fact table in AS which would then be used to create a many-to-many relationship from your other Fact table to the Athlete Team table.

|||

Matt,

The way you have explanied of breaking the Group Key from the Athelete Team table/dimension is the best thing to do.

Anyway, we have gone ahead and changed our data model to the way exactly SSAS handles, viz. by factless fact tables.

Thanks for the inputs.

Vivek

many to many relationship inserts

Hi all

I have a SQL Server 2000 database that I converted from an access database. The interface is still existing in Access...

Basically I have 2 tables in a many to many relationship - Member and Nominators of members. But because the same nominator can nominate many members and a member can be nominated by multiple nominators, i've added a linking table call MemberNomLink that has the MemberId and the NominatorId.

So in my access interface I have a parent form for the Member, and a subform of all the nominators for that member. When i enter, if the nominator is brand new (never nominated before) then I'd just do an insert - which would:

a) insert into the nominator form (giving a new IDENTITY Primary key - Nominator Id) and
b) would insert into the MemberNomLink table - the new NominatorId and the parent form's Member Id.

When I was running this in access, this worked fine by simply using a left join query on my subform between Nominators and MemberNomLink. When I inserted into this query, access seemed to automatically insert nominator, then create the MemberNomLink fine populating it with the new id.

When I'm attached to the SQL Server 2000 db though, it will insert into the nominator table, however it won't insert into the MemberNomLink.

I don't think this is an unusual circumstance but if anyone has done anything like this, I'd like to know if I'm doing something obviously wrong...

thanks in advance
scott

Quote:

Originally Posted by smook

Hi all

I have a SQL Server 2000 database that I converted from an access database. The interface is still existing in Access...

Basically I have 2 tables in a many to many relationship - Member and Nominators of members. But because the same nominator can nominate many members and a member can be nominated by multiple nominators, i've added a linking table call MemberNomLink that has the MemberId and the NominatorId.

So in my access interface I have a parent form for the Member, and a subform of all the nominators for that member. When i enter, if the nominator is brand new (never nominated before) then I'd just do an insert - which would:

a) insert into the nominator form (giving a new IDENTITY Primary key - Nominator Id) and
b) would insert into the MemberNomLink table - the new NominatorId and the parent form's Member Id.

When I was running this in access, this worked fine by simply using a left join query on my subform between Nominators and MemberNomLink. When I inserted into this query, access seemed to automatically insert nominator, then create the MemberNomLink fine populating it with the new id.

When I'm attached to the SQL Server 2000 db though, it will insert into the nominator table, however it won't insert into the MemberNomLink.

I don't think this is an unusual circumstance but if anyone has done anything like this, I'd like to know if I'm doing something obviously wrong...

thanks in advance
scott



You can achieve the same functionality using a 'trigger' in SQL although I have to say the after_update event of the appropriate NominatorID field in your interface could be used primarily to determine if apropriate values exists in the MemberNomLink table and if not to then insert them immediately following an insertion of a new nominator. You would then simply requery to refresh the interface.

What format frontend are you using MDB or ADP? Have a good look at the ADP format in Access if you are upsizing for the first time. You can choose either of these of course whichever you arecomfortable with, however the ADP format handily exposes views and stored procedures to you in the interface and connects directly to SQL server using UDL Universal data link ie it doesnt use ODBC connectivity. If you need to create tables locally on the client then stick with the MDB format (mdb is back in favour for Access 2007 too)

Have a go at the after update event based on my simple response here and if you get stuck then post your table structure ie 'exact' table and field names and I'll replicate the tables and necessary SQL on my server, create MDB and an ADP solutions to show you the relevant differences and then mail you the files which should work on your system provided the db name is the same too. Don't post your email address though. (if this progresses to that) you would have to PM me with it and I,ll mail you

Regards

Jim :)

many to many relationship in OLAP

Hi, this is a question about many to many relationship in Analysis services cube.

We have an Analysis services OLAP cube for reporting the amount of sold goods. One of the dimensions is customers another dimension is sales person. One sale person takes care of more than one customer and one costumer can be hold by more than one sales person. (many to many relationship, for connecting table customers and sales person I used intermediate table)

The problem is when one customer has, for example, two sales persons (A and B). If I chose just sale person A from sales person dimension everything is O.K. (Row area - customers, Column area - time dimension, Excel XP) but if I want to see how much was sold by both A and B, the data (amount of sold goods) is multiplied twice. (e.g. on 01.01.03 was sold to customer XX just 100 items and not 200 even though two sales person sold them) I am looking for something like distinct sum.

Can you suggest any solution to this problem?

Thanks in advance,

Daviddont summarize based on this data

you can:

a). not summarize based on this data

b). create a percentage of sales-- so that if 9 sales people are assigned to an account, then they each get 11% of the sales.|||So you think there is no other way how to solve my problem. We have more of these cases.|||uh there are a hundred ways to solve this

i would try to solve it on the database side, and not the OLAP side-- it is going to be a lot eaiser.

i deal with this all the time, and i have a cube for employee sales and then a cube for total sales.

let me look into this a little bit better..

im an olap developer and just generally avoid many to many.. but maybe there is a logical way to do this

(to be truthful, when i have a many to many, i shape the data using DTS in order to flatten it into a snowflake)--

isnt this just a snowflake schema?

maybe you could create a table that would assign a bunch of salespeople and then you assign the group to the record..

and allow drilldown to see what people are in a group--

but this seems oversimplified..

cant you just make a list of all of the sales people for each customer, and list it in text?

like you would push into a database field all of the sales reps for a particular order-- IE, 'John Smith, April Johnson, Mark Kay Latorneau' etc

this really wouldnt be that difficult to accomplish...|||thanks for advice

Many to many relationship in MSAS

Hi,

I ve got a fact table called project_fact and a dimension table called technology_dim.

project_fact:

proj_id time_id tech_id revenue cost

technology_dim:

tech_id tech_name

Now there is a many to many relation between fact and dimension table. one project can be done on many technologies. How to resolve this, do i need to create a third table?

Please tell me in details...

Thanks in advance,

Siddharth Rai.

Create a table that represents the combination of technologies exploited by your project. Let's call this the TechGroup table:

create table TechGroup (

TechGroupID int not null identity(1,1)

)

alter table TechGroup add

constraint PK_TechGroup primary key (techgroupid)

Create another tables that relates the TechGroup to the Technologies that comprise it:

create table TechGroupTechnologyBridge (

TechGroupID int not null,

TechnologyID int not null

)

alter table TechGroupTechnologyBridge add

constraint PK_TechGroupTechnologyBridge primary key (techgroupid, technologyid),

constraint FK_TechGroupTechnologyBridge_TechGroupID foreign key (techgroupid) references TechGroup (techgroupid),

constraint FK_TechGroupTechnologyBridge_TechnologyID foreign key (technologyid) references Technology (technologyid)

In your fact table, reference the TechGroup table.

When you set up the cube, create a TechGroup dimension. Add the TechGroupTechnologyBridge as a measure group with a single measure (using COUNT). Make the measure not visible (which will hide the bridge measure group).

In your dimension usage tab, set the relationships between TechGroupTechnologyBridge measure group and TechGroup and Technology dimensions. Relate your fact table measure group to the TechGroup dimension as well.

Now, set a many-to-many relationship between your fact table and the Technology dimension using the TechGroupTechnologyBridge measure group as the intermediate measure group.

You will probably want to make the TechGroup dimension not visible within your cube.

Good luck,
Bryan

|||

Hey thanks Bryan...sql

Many to many relationship in MSAS

Hi,

I ve got a fact table called project_fact and a dimension table called technology_dim.

project_fact:

proj_id time_id tech_id revenue cost

technology_dim:

tech_id tech_name

Now there is a many to many relation between fact and dimension table. one project can be done on many technologies. How to resolve this, do i need to create a third table?

Please tell me in details...

Thanks in advance,

Siddharth Rai.

Create a table that represents the combination of technologies exploited by your project. Let's call this the TechGroup table:

create table TechGroup (

TechGroupID int not null identity(1,1)

)

alter table TechGroup add

constraint PK_TechGroup primary key (techgroupid)

Create another tables that relates the TechGroup to the Technologies that comprise it:

create table TechGroupTechnologyBridge (

TechGroupID int not null,

TechnologyID int not null

)

alter table TechGroupTechnologyBridge add

constraint PK_TechGroupTechnologyBridge primary key (techgroupid, technologyid),

constraint FK_TechGroupTechnologyBridge_TechGroupID foreign key (techgroupid) references TechGroup (techgroupid),

constraint FK_TechGroupTechnologyBridge_TechnologyID foreign key (technologyid) references Technology (technologyid)

In your fact table, reference the TechGroup table.

When you set up the cube, create a TechGroup dimension. Add the TechGroupTechnologyBridge as a measure group with a single measure (using COUNT). Make the measure not visible (which will hide the bridge measure group).

In your dimension usage tab, set the relationships between TechGroupTechnologyBridge measure group and TechGroup and Technology dimensions. Relate your fact table measure group to the TechGroup dimension as well.

Now, set a many-to-many relationship between your fact table and the Technology dimension using the TechGroupTechnologyBridge measure group as the intermediate measure group.

You will probably want to make the TechGroup dimension not visible within your cube.

Good luck,
Bryan

|||Hey thanks Bryan...

many to many relationship - whats best way to add/edit/delete

I have a many to many relationship

I can design the table 2 ways:

1) Category table (cat_id, cat_name, active) - cat_id as PK
CategoryReq (cat_id, req_name) - cat_id & req_name as PK

2)
CategoryReq (req_name, cat_name) - req_name & cat_name as PK

IfI design 1st way. Then when they want to add and delete from theCategoryRequest table, they would have to add to the category tablefirst. Then maybe build a list of checkboxes to select from. The one'sthey check insert into the CategoryRequest table.

Drawback ofthis is that they can't edit the list on the fly. Since it may be usedby other request (since cat_id CategoryReq is fk into Category table)

If I design it the 2nd way. Then they can edit, delete, add on the fly. But there won't be a master category list.

Which way is better?

Hi,

The design of the database strictly derives from the application requirements. But as a rule of thumb, you should generally create normalized tables to the third normal form in RDBMS theory. And then denormalize only if necessary. (Usually, the main reason for denormalization is performance improvement). Denormalization can be very harmful. Do it sparingly and only if you know what are you doing!

many to many relationship

hi all,
how to implement the many to many relation ship...
i get stucked it......
plz help
thanx
sajjadhere's a good example -- http://www.dbforums.com/t1094761.html|||thanx for reply man
can u explain the briefly background theory of Many to Many relation ship|||http://www.utexas.edu/its/windows/database/datamodeling/rm/rm4.html