Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase

Relational design question Expand / Collapse
Author
Message
Posted Friday, January 06, 2012 1:23 PM


SSC Journeyman

SSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC Journeyman

Group: General Forum Members
Last Login: Friday, March 01, 2013 12:29 PM
Points: 99, Visits: 327
I am working on a project, and I've hit a small-ish bump in the road. I have to link a client to multiple product types. I need this to allow for various numbers of products, and several of the same products are sold by different clients. Here is a better overview of the data:

Create Table dbo.Clients
(Client_ID Int Identity(1,1) Primary Key
,ClientName Varchar(100))
Go

--------------------
Create Table dbo.Products
(Product_ID Int Identity(1,1) Primary Key
,ProductName Varchar(100))
Go

--------------------
Insert Into dbo.Clients
(ClientName)
Select 'Client 1'
Union All
Select 'Client 2'
Go

--------------------
Insert Into dbo.Products
(ProductName)
Select 'Product 1'
Union All
Select 'Product 2'
Union All
Select 'Product 3'
Go

Now, my thought is to use an asoc table...something along the lines of:

Create Table Client_Products_Asoc
(Client_Products_Asoc_ID Int Identity(1,1) Primary Key
,Client_ID Int References dbo.Clients(Client_ID)
,Product_ID Int References dbo.Products(Product_ID))
Go

--------------------
Insert Into dbo.Client_Products_Asoc
(Client_ID
,Product_ID)
Select 1,1
Union All
Select 1,3
Union All
Select 2,1
Union All
Select 2,2
Go

Am I over thinking this? I know I can create a cross-tab query using this logic, but is there an easier way to go about this?


“Any fool can know. The point is to understand.”
- Albert Einstein

"DOH!"
- Homer Simpson
Post #1231714
Posted Friday, January 06, 2012 1:33 PM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 3:30 PM
Points: 2,982, Visits: 4,397
jarid.lawson (1/6/2012)
Am I over thinking this?

Nope, you are not.

As far as I understand the scenario there is a many-to-many relationship between Clients and Products - the bridge table breaks that n-n relationship which is IMHO the sensible thing to do.


_____________________________________
Pablo (Paul) Berzukov

Author of Understanding Database Administration available at Amazon and other bookstores.

Disclaimer: Advice is provided to the best of my knowledge but no implicit or explicit warranties are provided. Since the advisor explicitly encourages testing any and all suggestions on a test non-production environment advisor should not held liable or responsible for any actions taken based on the given advice.
Post #1231722
Posted Friday, January 06, 2012 1:40 PM


SSC Journeyman

SSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC Journeyman

Group: General Forum Members
Last Login: Friday, March 01, 2013 12:29 PM
Points: 99, Visits: 327
Thanks for the reassurance. I'm designing a new financial tracking system as the company's new DBA...and I'm trying to do this as perfect as I can from the start. It has been a long time since I've done something this big, so I am a little nervous.

I appreciate you taking the time to answer.


“Any fool can know. The point is to understand.”
- Albert Einstein

"DOH!"
- Homer Simpson
Post #1231726
Posted Friday, January 06, 2012 1:43 PM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 3:30 PM
Points: 2,982, Visits: 4,397
jarid.lawson (1/6/2012)
Thanks for the reassurance. I'm designing a new financial tracking system as the company's new DBA...and I'm trying to do this as perfect as I can from the start. It has been a long time since I've done something this big, so I am a little nervous.

I appreciate you taking the time to answer.


No worries. Just trust your instincts, I've seen your posts - you are good


_____________________________________
Pablo (Paul) Berzukov

Author of Understanding Database Administration available at Amazon and other bookstores.

Disclaimer: Advice is provided to the best of my knowledge but no implicit or explicit warranties are provided. Since the advisor explicitly encourages testing any and all suggestions on a test non-production environment advisor should not held liable or responsible for any actions taken based on the given advice.
Post #1231728
Posted Wednesday, January 11, 2012 1:35 PM
SSC-Addicted

SSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-Addicted

Group: General Forum Members
Last Login: Today @ 3:49 PM
Points: 406, Visits: 2,852
jarid.lawson (1/6/2012)
I am working on a project, and I've hit a small-ish bump in the road. I have to link a client to multiple product types. I need this to allow for various numbers of products, and several of the same products are sold by different clients. Here is a better overview of the data:

I see some potential problems. Is there a reason why you are allowing products with duplicate names and clients with duplicate names? Why permit null product names and client names? How will the users be able to identify the clients and products accurately in those tables?

Create Table Client_Products_Asoc
(Client_Products_Asoc_ID Int Identity(1,1) Primary Key
,Client_ID Int References dbo.Clients(Client_ID)
,Product_ID Int References dbo.Products(Product_ID))
Go

The Client_Products_Asoc table means that one client can be associated with the same product multiple times. That seems unlikely to be useful or correct. Also both client and product IDs are nullable, which means you could get clients without associated products and products without associated clients, in which case what would be the purpose of having them in this table?

Hope this helps.


David
Post #1234341
Posted Wednesday, January 11, 2012 3:49 PM


SSC Journeyman

SSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC Journeyman

Group: General Forum Members
Last Login: Friday, March 01, 2013 12:29 PM
Points: 99, Visits: 327
These are great questions. Let me see if I can explain my logic.

Client 1 Offers
Product 1
Product 2
Product 4

Client 2 Offers
Product 2
Product 4
Product 5

I want to be able to run reports that list sales by client by product. To do this I would
Select C.Name As ClientName
,P.Name As ProductName
,Sum(P.Sales) As TotalSales
From dbo.Client C Inner Join dbo.ClientProduct_Asoc CPA
On C.Client_ID = CPA.Client_ID
Inner Join dbo.Product P
On P.Product_ID = CPA.Product_ID
Where CPA.Inactive <> 'Y'

Granted this is a quick version of my logic, but does that explain it a little better? Or is there a better way to do this?


“Any fool can know. The point is to understand.”
- Albert Einstein

"DOH!"
- Homer Simpson
Post #1234438
Posted Wednesday, January 11, 2012 3:52 PM


SSC Journeyman

SSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC Journeyman

Group: General Forum Members
Last Login: Friday, March 01, 2013 12:29 PM
Points: 99, Visits: 327
Sorry, I just saw that I forgot to include a vital part of my logic to why I am doing things this way. I have a transactions table which shows each of the products. Each transaction will include Client_ID and Product_ID on each line, so they can link this way.

“Any fool can know. The point is to understand.”
- Albert Einstein

"DOH!"
- Homer Simpson
Post #1234440
Posted Wednesday, January 11, 2012 6:18 PM


SSC-Addicted

SSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-Addicted

Group: General Forum Members
Last Login: Friday, April 19, 2013 2:23 PM
Points: 494, Visits: 1,110
Create Table Client_Products_Asoc(Client_Products_Asoc_ID Int Identity(1,1) Primary Key ,Client_ID Int References dbo.Clients(Client_ID) ,Product_ID Int References dbo.Products(Product_ID))Go



Logically, the ClientID + ProductID should be unique so you can use them together as a composite key. This should help avoid nulls and duplicates in the associating table.

Something like:

	--this table identifies the clients
Create Table Clients(
Client_ID Int Identity(1,1) Primary Key ,
ClientName Varchar(100))
Go

Insert Into Clients(ClientName)
Select 'Client 1'
Union All
Select 'Client 2'
Go
--------------------
--this table identifies the products, i'm assuming there will be more columns
Create Table Products(
Product_ID Int Identity(1,1) Primary Key ,
ProductName Varchar(100),
ProductCost Decimal(28,4))
Go

Insert Into Products(ProductName, ProductCost)
Select 'Product 1' , 49.95
Union All
Select 'Product 2' , 15
Union All
Select 'Product 3' , 777.77
Go
--------------------
--this table associates the clients and products and provides a place for custom name
Create Table Client_Products(
Client_ID Int References Clients(Client_ID) not null,
Product_ID Int References Products(Product_ID) not null,
ClientProductName varchar(100) null,
PRIMARY KEY (Client_ID, Product_ID)
)
Go

Insert Into Client_Products (Client_ID , Product_ID , ClientProductName )
select 1,1,null
union all
select 1,2, 'Beer Popsicle'
union all
select 2,2, null
union all
select 2,3, 'Our Thingy'
union all
select 1,3, null
Go
--------------------
--if you want to see which products a client is associated with
select
c.client_ID
,c.ClientName
,p.Product_ID
,coalesce(cp.ClientProductName, p.ProductName)

from
Client_Products cp
inner join Clients c on c.Client_ID = cp.Client_ID
inner join Products p on p.Product_ID = cp.Product_ID
;
--------------------
--you said you have a transaction table, this is a dummy version without your ddl
--just to show how to pull out data

Create Table ClientTransactions(Client_ID Int, Product_ID Int, Quantity Int)
go
Insert Into ClientTransactions
select 1,1,40 union all
select 1,2,200 union all
select 1,3,10 union all
select 1,1,16 union all
select 2,1,1 union all
select 2,2,50 union all
select 2,3,40 union all
select 1,2,6 union all
select 2,3,4
go

select
c.client_ID
,c.ClientName
,p.Product_ID
,coalesce(cp.ClientProductName, p.ProductName)
,TotalQuantity=SUM(t.Quantity)
,TotalPrice=SUM(t.Quantity * p.ProductCost)

from
ClientTransactions t
inner join Clients c on c.Client_ID = t.Client_ID
inner join Products p on p.Product_ID = t.Product_ID
inner join Client_Products cp on cp.Client_ID = t.Client_ID and cp.Product_ID = t.Product_ID


group by
c.client_ID
,c.ClientName
,p.Product_ID
,coalesce(cp.ClientProductName, p.ProductName)
;





Looking for a Deadlock Victim Support Group..
Post #1234498
« Prev Topic | Next Topic »

Add to briefcase

Permissions Expand / Collapse