How to get set-based solution for a difficult join - sql

I've got a Table with a list of Products.
I've got a Table with a list of Merchants.
I've got a Table with a list of Warehouses.
I've got a WarehouseMerchant Table so a a warehouse can have many merchants assigned.
I've got a WarehouseMerchantProduct Table so a merchant can have its products listed in a warehouse
I've got a Merchant Link Table which can link 2 merchants
MerchantLinkID int
MasterMerchantID int
LinkedMerchantID int
PreferenceOrder int
What i need to do is pass in a product ID and get a unique list of merchants products who can sell it.
4 Rules
If the merchant has a linked merchant who also sells the product, then don't show the linked merchants product
If the merchant has a linked merchant who also sells the product, but the master merchants stock level is 0, then only show the linked merchants product
In the event that a merchant has stock in multiple warehouses, then there is a preference order in the warehouseMerchant Table to select which one to use
There should only be one product per merchant after this has all ran
I've been racking my brains trying to figure out a solution. I was going down the route of cursors, but it was getting a bit unwieldy. Then i was given the 4 rules as a requirement which sent me back to the drawing board.
If anyone can think of a quick and easy(ish) set-based solution for this then I'd love to hear it.
Here is the script to create the tables and relationships
CREATE TABLE [dbo].[MW_Merchant](
[MerchantID] [int] IDENTITY(1,1) NOT NULL,
[MerchantName] [nvarchar](150) NOT NULL,
[MerchantCode] [char](10) NOT NULL,
[Active] [bit] NOT NULL,
CONSTRAINT [PK_Merchant] PRIMARY KEY CLUSTERED
(
[MerchantID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [ucMerchantCode] UNIQUE NONCLUSTERED
(
[MerchantCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[MW_Warehouse] Script Date: 04/30/2013 09:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[MW_Warehouse](
[WarehouseID] [int] IDENTITY(1,1) NOT NULL,
[WarehouseName] [nvarchar](150) NOT NULL,
[WarehouseCode] [varchar](10) NOT NULL,
[Active] [bit] NOT NULL,
CONSTRAINT [PK_Warehouse] PRIMARY KEY CLUSTERED
(
[WarehouseID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[MW_WarehouseMerchantProduct] Script Date: 04/30/2013 09:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[MW_WarehouseMerchantProduct](
[WarehouseMerchantProductID] [int] IDENTITY(1,1) NOT NULL,
[WarehouseID] [int] NOT NULL,
[MerchantID] [int] NOT NULL,
[ProductCode] [varchar](30) NOT NULL,
[StockLevel] [int] NOT NULL,
[Active] [bit] NOT NULL,
[PriorityOrder] [int] NOT NULL,
CONSTRAINT [PK_MW_WarehouseProduct] PRIMARY KEY CLUSTERED
(
[WarehouseMerchantProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[MW_WarehouseMerchant] Script Date: 04/30/2013 09:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MW_WarehouseMerchant](
[WarehouseMerchantID] [int] IDENTITY(1,1) NOT NULL,
[WarehouseID] [int] NOT NULL,
[MerchantID] [int] NOT NULL,
[Active] [bit] NOT NULL,
[PreferenceOrder] [int] NOT NULL,
CONSTRAINT [PK_MW_WarehouseMerchant] PRIMARY KEY CLUSTERED
(
[WarehouseMerchantID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[MW_MerchantLink] Script Date: 04/30/2013 09:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MW_MerchantLink](
[MerchantLinkID] [int] IDENTITY(1,1) NOT NULL,
[MasterMerchantID] [int] NOT NULL,
[LinkedMerchantID] [int] NOT NULL,
[PreferenceOrder] [int] NOT NULL,
CONSTRAINT [PK_MW_MerchantLink] PRIMARY KEY CLUSTERED
(
[MerchantLinkID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Default [DF_MW_WarehouseMerchant_PreferenceOrder] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchant] ADD CONSTRAINT [DF_MW_WarehouseMerchant_PreferenceOrder] DEFAULT ((10)) FOR [PreferenceOrder]
GO
/****** Object: Default [DF_MW_WarehouseMerchantProduct_PriorityOrder] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] ADD CONSTRAINT [DF_MW_WarehouseMerchantProduct_PriorityOrder] DEFAULT ((10)) FOR [PriorityOrder]
GO
/****** Object: ForeignKey [FK_MW_MerchantLink_MW_Merchant] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_MerchantLink] WITH CHECK ADD CONSTRAINT [FK_MW_MerchantLink_MW_Merchant] FOREIGN KEY([MasterMerchantID])
REFERENCES [dbo].[MW_Merchant] ([MerchantID])
GO
ALTER TABLE [dbo].[MW_MerchantLink] CHECK CONSTRAINT [FK_MW_MerchantLink_MW_Merchant]
GO
/****** Object: ForeignKey [FK_MW_MerchantLink_MW_Merchant1] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_MerchantLink] WITH CHECK ADD CONSTRAINT [FK_MW_MerchantLink_MW_Merchant1] FOREIGN KEY([LinkedMerchantID])
REFERENCES [dbo].[MW_Merchant] ([MerchantID])
GO
ALTER TABLE [dbo].[MW_MerchantLink] CHECK CONSTRAINT [FK_MW_MerchantLink_MW_Merchant1]
GO
/****** Object: ForeignKey [FK_MW_WarehouseMerchant_MW_Merchant] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchant] WITH CHECK ADD CONSTRAINT [FK_MW_WarehouseMerchant_MW_Merchant] FOREIGN KEY([MerchantID])
REFERENCES [dbo].[MW_Merchant] ([MerchantID])
GO
ALTER TABLE [dbo].[MW_WarehouseMerchant] CHECK CONSTRAINT [FK_MW_WarehouseMerchant_MW_Merchant]
GO
/****** Object: ForeignKey [FK_MW_WarehouseMerchant_MW_Warehouse] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchant] WITH CHECK ADD CONSTRAINT [FK_MW_WarehouseMerchant_MW_Warehouse] FOREIGN KEY([WarehouseID])
REFERENCES [dbo].[MW_Warehouse] ([WarehouseID])
GO
ALTER TABLE [dbo].[MW_WarehouseMerchant] CHECK CONSTRAINT [FK_MW_WarehouseMerchant_MW_Warehouse]
GO
/****** Object: ForeignKey [FK_MW_WarehouseMerchantProduct_MW_Merchant] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] WITH CHECK ADD CONSTRAINT [FK_MW_WarehouseMerchantProduct_MW_Merchant] FOREIGN KEY([MerchantID])
REFERENCES [dbo].[MW_Merchant] ([MerchantID])
GO
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] CHECK CONSTRAINT [FK_MW_WarehouseMerchantProduct_MW_Merchant]
GO
/****** Object: ForeignKey [FK_MW_WarehouseProduct_MW_Warehouse] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] WITH CHECK ADD CONSTRAINT [FK_MW_WarehouseProduct_MW_Warehouse] FOREIGN KEY([WarehouseID])
REFERENCES [dbo].[MW_Warehouse] ([WarehouseID])
GO
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] CHECK CONSTRAINT [FK_MW_WarehouseProduct_MW_Warehouse]
GO
And some test data
/****** Object: Table [dbo].[MW_Merchant] Script Date: 04/30/2013 09:41:50 ******/
SET IDENTITY_INSERT [dbo].[MW_Merchant] ON
INSERT [dbo].[MW_Merchant] ([MerchantID], [MerchantName], [MerchantCode], [Active]) VALUES (24, N'Merchant 1', N'MERCH1 ', 1)
INSERT [dbo].[MW_Merchant] ([MerchantID], [MerchantName], [MerchantCode], [Active]) VALUES (27, N'Merchant 2', N'MERCH2 ', 1)
INSERT [dbo].[MW_Merchant] ([MerchantID], [MerchantName], [MerchantCode], [Active]) VALUES (28, N'Merchant 3', N'MERCH3 ', 1)
SET IDENTITY_INSERT [dbo].[MW_Merchant] OFF
/****** Object: Table [dbo].[MW_Warehouse] Script Date: 04/30/2013 09:41:50 ******/
SET IDENTITY_INSERT [dbo].[MW_Warehouse] ON
INSERT [dbo].[MW_Warehouse] ([WarehouseID], [WarehouseName], [WarehouseCode], [Active]) VALUES (12, N'Warehouse 1', N'WARE1', 1)
INSERT [dbo].[MW_Warehouse] ([WarehouseID], [WarehouseName], [WarehouseCode], [Active]) VALUES (13, N'Warehouse 2', N'WARE2', 1)
INSERT [dbo].[MW_Warehouse] ([WarehouseID], [WarehouseName], [WarehouseCode], [Active]) VALUES (14, N'Warehouse 3', N'WARE3', 1)
SET IDENTITY_INSERT [dbo].[MW_Warehouse] OFF
/****** Object: Table [dbo].[MW_WarehouseMerchantProduct] Script Date: 04/30/2013 09:41:50 ******/
SET IDENTITY_INSERT [dbo].[MW_WarehouseMerchantProduct] ON
INSERT [dbo].[MW_WarehouseMerchantProduct] ([WarehouseMerchantProductID], [WarehouseID], [MerchantID], [ProductCode], [StockLevel], [Active], [PriorityOrder]) VALUES (93, 13, 24, N'TESTPRODUCT', 20, 1, 10)
INSERT [dbo].[MW_WarehouseMerchantProduct] ([WarehouseMerchantProductID], [WarehouseID], [MerchantID], [ProductCode], [StockLevel], [Active], [PriorityOrder]) VALUES (96, 14, 24, N'TESTPRODUCT', 20, 1, 10)
INSERT [dbo].[MW_WarehouseMerchantProduct] ([WarehouseMerchantProductID], [WarehouseID], [MerchantID], [ProductCode], [StockLevel], [Active], [PriorityOrder]) VALUES (97, 14, 27, N'TESTPRODUCT', 10, 1, 10)
SET IDENTITY_INSERT [dbo].[MW_WarehouseMerchantProduct] OFF
/****** Object: Table [dbo].[MW_MerchantLink] Script Date: 04/30/2013 09:41:50 ******/
SET IDENTITY_INSERT [dbo].[MW_MerchantLink] ON
INSERT [dbo].[MW_MerchantLink] ([MerchantLinkID], [MasterMerchantID], [LinkedMerchantID], [PreferenceOrder]) VALUES (22, 24, 27, 1)
INSERT [dbo].[MW_MerchantLink] ([MerchantLinkID], [MasterMerchantID], [LinkedMerchantID], [PreferenceOrder]) VALUES (23, 24, 28, 2)
SET IDENTITY_INSERT [dbo].[MW_MerchantLink] OFF
In the example data, my returned row should be the WarehouseMerchantProductID 93
93,96 and 97 all have stock, however
93 and 96 belong to the same merchant and should be selected based on PreferenceOrder in the WarehouseMerchant Table
Merchant 27 is linked to 24 so shouldnt appear (unless 24 goes out of stock)

Note, the following query is written for Oracle and assumes that a LinkedMerchant only has 1 MasterMerchant. You can play around with the code here. Also note that I have included more test data than you provided in order to test some additional cases.
SELECT MERCHANTID, WAREHOUSEID, PRODUCTCODE
FROM (
SELECT 0
, WMP.MERCHANTID
, WMP.WAREHOUSEID
, WMP.PRODUCTCODE
, RANK() OVER (PARTITION BY ML.MASTERMERCHANTID, WMP.PRODUCTCODE ORDER BY ML.PREFERENCEORDER ASC NULLS LAST) MERCH_RANK
, RANK() OVER (PARTITION BY WMP.MERCHANTID, WMP.PRODUCTCODE ORDER BY WM.PREFERENCEORDER ASC NULLS LAST) WARE_RANK
FROM MW_WAREHOUSEMERCHANTPRODUCT WMP
LEFT OUTER JOIN MW_WAREHOUSEMERCHANT WM ON 0=0
AND WMP.MERCHANTID = WM.MERCHANTID
AND WMP.WAREHOUSEID = WM.WAREHOUSEID
LEFT OUTER JOIN MW_MERCHANTLINK ML ON 0=0
AND WMP.MERCHANTID = ML.LINKEDMERCHANTID
LEFT OUTER JOIN MW_WAREHOUSEMERCHANTPRODUCT MASTER ON 0=0
AND ML.MASTERMERCHANTID = MASTER.MERCHANTID
AND WMP.PRODUCTCODE = MASTER.PRODUCTCODE
WHERE 0=0
AND WMP.STOCKLEVEL > 0
AND NVL(MASTER.STOCKLEVEL, 0) <= 0
)
WHERE 0=0
AND MERCH_RANK = 1
AND WARE_RANK = 1
;

Related

Create tables for Dynamic Product

I want user can create Product category And if it Have SubCategory.define SubCategory.then define column in tables(Brand,Group And Field) Of that Category(or SubCategory).Finally user can add Product Based that Brand,Group And Field column that define before.
I Want to create Dynamic Product Database and this my first time for create dynamic tables.I just worry about
1-Correct Creation
2-performance issue(no doubt about types).
I add my diagram Tables and script of tables
CREATE TABLE [dbo].[CategoryBrand](
[ProductCategoryId] [tinyint] NOT NULL,
[ProductBrandId] [tinyint] NOT NULL,
CONSTRAINT [PK_CategoryBrand] PRIMARY KEY CLUSTERED
(
[ProductCategoryId] ASC,
[ProductBrandId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Group] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Group](
[Id] [smallint] IDENTITY(1,1) NOT NULL,
[ProductCategoryId] [tinyint] NOT NULL,
[GroupName] [nvarchar](250) NOT NULL,
CONSTRAINT [PK_aaa] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[GroupInfo] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[GroupInfo](
[Id] [int] IDENTITY(1,1) NOT NULL,
[GroupId] [smallint] NOT NULL,
[SubGroupName] [nvarchar](500) NOT NULL,
CONSTRAINT [PK_GroupInfo] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Product] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Product](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CategoryId] [tinyint] NOT NULL,
[Describtion] [nvarchar](max) NULL,
[ProductBrandId] [tinyint] NOT NULL,
CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/****** Object: Table [dbo].[ProductBrand] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductBrand](
[Id] [tinyint] IDENTITY(1,1) NOT NULL,
[BrandName] [nvarchar](50) NOT NULL,
[ImageAddress] [nvarchar](500) NULL,
CONSTRAINT [PK_ProductBrand] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[ProductCategory] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductCategory](
[Id] [tinyint] IDENTITY(1,1) NOT NULL,
[Category] [nvarchar](250) NOT NULL,
[ParentId] [tinyint] NULL,
CONSTRAINT [PK_ProductCategory] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[ProductField] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductField](
[Id] [smallint] IDENTITY(1,1) NOT NULL,
[ProductCategoryId] [tinyint] NOT NULL,
[FieldName] [nvarchar](100) NOT NULL,
[Describtion] [nvarchar](1000) NULL,
CONSTRAINT [PK_ProductField] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[ProductFieldInfo] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductFieldInfo](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ProductId] [int] NOT NULL,
[ProductFieldId] [smallint] NOT NULL,
[FieldInfo] [nvarchar](1000) NOT NULL,
CONSTRAINT [PK_ProductFieldInfo] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[ProductGroup] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductGroup](
[ProductId] [int] NOT NULL,
[GroupIfoId] [int] NOT NULL,
CONSTRAINT [PK_ProductGroup] PRIMARY KEY CLUSTERED
(
[ProductId] ASC,
[GroupIfoId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[ProductImage] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductImage](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ProductId] [int] NOT NULL,
[FileName] [nvarchar](500) NULL,
[ImageAddress] [nvarchar](500) NOT NULL,
CONSTRAINT [PK_ProductImage] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[CategoryBrand] WITH CHECK ADD CONSTRAINT [FK_CategoryBrand_ProductBrand] FOREIGN KEY([ProductBrandId])
REFERENCES [dbo].[ProductBrand] ([Id])
GO
ALTER TABLE [dbo].[CategoryBrand] CHECK CONSTRAINT [FK_CategoryBrand_ProductBrand]
GO
ALTER TABLE [dbo].[CategoryBrand] WITH CHECK ADD CONSTRAINT [FK_CategoryBrand_ProductCategory] FOREIGN KEY([ProductCategoryId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[CategoryBrand] CHECK CONSTRAINT [FK_CategoryBrand_ProductCategory]
GO
ALTER TABLE [dbo].[Group] WITH CHECK ADD CONSTRAINT [FK_aaa_ProductCategory] FOREIGN KEY([ProductCategoryId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[Group] CHECK CONSTRAINT [FK_aaa_ProductCategory]
GO
ALTER TABLE [dbo].[GroupInfo] WITH CHECK ADD CONSTRAINT [FK_GroupInfo_aaa] FOREIGN KEY([GroupId])
REFERENCES [dbo].[Group] ([Id])
GO
ALTER TABLE [dbo].[GroupInfo] CHECK CONSTRAINT [FK_GroupInfo_aaa]
GO
ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [FK_Product_ProductBrand] FOREIGN KEY([ProductBrandId])
REFERENCES [dbo].[ProductBrand] ([Id])
GO
ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_Product_ProductBrand]
GO
ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [FK_Product_ProductCategory] FOREIGN KEY([CategoryId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_Product_ProductCategory]
GO
ALTER TABLE [dbo].[ProductCategory] WITH CHECK ADD CONSTRAINT [FK_ProductCategory_ProductCategory] FOREIGN KEY([ParentId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[ProductCategory] CHECK CONSTRAINT [FK_ProductCategory_ProductCategory]
GO
ALTER TABLE [dbo].[ProductField] WITH CHECK ADD CONSTRAINT [FK_ProductField_ProductCategory] FOREIGN KEY([ProductCategoryId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[ProductField] CHECK CONSTRAINT [FK_ProductField_ProductCategory]
GO
ALTER TABLE [dbo].[ProductFieldInfo] WITH CHECK ADD CONSTRAINT [FK_ProductFieldInfo_Product] FOREIGN KEY([ProductId])
REFERENCES [dbo].[Product] ([Id])
GO
ALTER TABLE [dbo].[ProductFieldInfo] CHECK CONSTRAINT [FK_ProductFieldInfo_Product]
GO
ALTER TABLE [dbo].[ProductFieldInfo] WITH CHECK ADD CONSTRAINT [FK_ProductFieldInfo_ProductField] FOREIGN KEY([ProductFieldId])
REFERENCES [dbo].[ProductField] ([Id])
GO
ALTER TABLE [dbo].[ProductFieldInfo] CHECK CONSTRAINT [FK_ProductFieldInfo_ProductField]
GO
ALTER TABLE [dbo].[ProductGroup] WITH CHECK ADD CONSTRAINT [FK_ProductGroup_GroupInfo] FOREIGN KEY([GroupIfoId])
REFERENCES [dbo].[GroupInfo] ([Id])
GO
ALTER TABLE [dbo].[ProductGroup] CHECK CONSTRAINT [FK_ProductGroup_GroupInfo]
GO
ALTER TABLE [dbo].[ProductGroup] WITH CHECK ADD CONSTRAINT [FK_ProductGroup_Product] FOREIGN KEY([ProductId])
REFERENCES [dbo].[Product] ([Id])
GO
ALTER TABLE [dbo].[ProductGroup] CHECK CONSTRAINT [FK_ProductGroup_Product]
GO
ALTER TABLE [dbo].[ProductImage] WITH CHECK ADD CONSTRAINT [FK_ProductImage_Product] FOREIGN KEY([ProductId])
REFERENCES [dbo].[Product] ([Id])
GO
ALTER TABLE [dbo].[ProductImage] CHECK CONSTRAINT [FK_ProductImage_Product]
GO
If it is your first time then make things simple.
Do not use dynamic SQL to create objects.
Before you do your design, review the well known AdventureWorks database. It has similar structure, where you can get some ideas:
http://msftdbprodsamples.codeplex.com/releases
If AdventureWorks will not satisfy you, then ask questions on how to modify it for your business needs.
I Find My Answer:
this is Database Table that I Want Design with Some Changes:
designing database to hold different metadata information

How to insert Foreignkey value into a table which doesnt exist yet

I have a situation, I have two tables namely ,User and Company .
Here is my User table :
CREATE TABLE [dbo].[User](
[UserId] [int] IDENTITY(1,1) NOT NULL,
[UserName] [nvarchar](500) NOT NULL,
[Password] [nvarchar](500) NOT NULL,
[CompanyId] [int] NULL,
[LastModUserId] [int] NOT NULL,
[LastModDttm] [datetime] NOT NULL,
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[User] WITH CHECK ADD CONSTRAINT [FK_User_Company] FOREIGN KEY([CompanyId])
REFERENCES [dbo].[Company] ([CompanyId])
GO
ALTER TABLE [dbo].[User] CHECK CONSTRAINT [FK_User_Company]
GO
ALTER TABLE [dbo].[User] WITH CHECK ADD CONSTRAINT [FK_User_User1] FOREIGN KEY([LastModUserId])
REFERENCES [dbo].[User] ([UserId])
GO
ALTER TABLE [dbo].[User] CHECK CONSTRAINT [FK_User_User1]
GO
Here is my Company Table :
CREATE TABLE [dbo].[Company](
[CompanyId] [int] IDENTITY(1,1) NOT NULL,
[CompanyName] [nvarchar](500) NOT NULL,
[Address1] [nvarchar](500) NULL,
[Address2] [nvarchar](500) NULL,
[LastModUserId] [int] NOT NULL,
[LastModDttm] [datetime] NOT NULL,
CONSTRAINT [PK_Company] PRIMARY KEY CLUSTERED
(
[CompanyId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Company] WITH CHECK ADD CONSTRAINT [FK_Company_User] FOREIGN KEY([LastModUserId])
REFERENCES [dbo].[User] ([UserId])
GO
ALTER TABLE [dbo].[Company] CHECK CONSTRAINT [FK_Company_User]
GO
My problem :
I want to create a company record,I haven't created a user yet.When I Insert into the LastModUserId columun it will throw the error "Cannot Insert the value NULL into column 'LastModUserId' ,table MYDb.dbo.Company' , column does not allow nulls.INSERT fails.
If I try to insert a record into the User Table ,there is also the same problem ,there is CompanyId column,which doesn't allow nulls either
How do I handle this situation ?
Disable constraint to enter super record.
ALTER TABLE [User] NOCHECK CONSTRAINT [FK_User_User1];
GO
ALTER TABLE [User] NOCHECK CONSTRAINT [FK_User_Company];
GO
DECLARE #USERID AS INT, #COMPANYID AS INT;
SELECT #USERID = 1, #COMPANYID = 1;
SET IDENTITY_INSERT [User] ON;
INSERT INTO [User](
[UserId],
[UserName],
[Password],
[CompanyId],
[LastModUserId],
[LastModDttm]
)
select
#USERID,
'Super',
'Passw0rd',
1,
1,
getdate();
SET IDENTITY_INSERT [User] OFF;
SET IDENTITY_INSERT [Company] ON;
insert into [Company](
[CompanyId],
[CompanyName],
[Address1],
[Address2],
[LastModUserId],
[LastModDttm])
select
#COMPANYID,
'cOMANY a',
'Address 1',
'Address 2',
#USERID,
getdate();
SET IDENTITY_INSERT [Company] OFF;
go
ALTER TABLE [User] CHECK CONSTRAINT [FK_User_User1];
GO
ALTER TABLE [User] CHECK CONSTRAINT [FK_User_Company];
GO

How to show the overall percentage of participation of each division in all sent quizzes?

I am a new web developer and I am developing a simple training management system which provides the users with quizzes. The system developed using ASP.NET and MS SQLServer. Now,
I need to come up with a query that shows the percentage of participation of each division in all the offered safety quizzes (which means quizzes with IsSent = true).
I have the following database design:
Employee Table: Username, Name, DivisionCode
Divisions Table: SapCode, Divison
Quiz Table: QuizID, Title, Description, IsSent
UserQuiz: UserQuizID, QuizID, DateTimeComplete, Username
(DivisionCode is a foreign key to the SapCode. IsSent is a flag to indicate to the quizzes that have been offered and sent to the users to participate in them.)
For example, If I have four divisions; A, B, C and D, and I have around 23 quizzes have been sent to the employees in those divisions. Since each division has a specific percentage of participation in each quiz. My query should show the overall percentage of participation in all offered quizzes for each division. So the result should not be broken down with respect to each quiz.
So how to do that?
And here's the schema of the database with its data:
USE [Test]
GO
/****** Object: Table [dbo].[Divisions] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Divisions](
[SapCode] [nvarchar](50) NOT NULL,
[Division] [varchar](50) NOT NULL,
CONSTRAINT [PK_Divisions] PRIMARY KEY CLUSTERED
(
[SapCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'1', N'A')
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'2', N'B')
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'3', N'C')
/****** Object: Table [dbo].[Quiz] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Quiz](
[QuizID] [int] IDENTITY(1,1) NOT NULL,
[Title] [varchar](50) NOT NULL,
[Description] [varchar](50) NOT NULL,
[IsSent] [bit] NOT NULL,
CONSTRAINT [PK_Quiz] PRIMARY KEY CLUSTERED
(
[QuizID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Quiz] ON
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (1, N'Quiz I', N'Test', 1)
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (2, N'Quiz II', N'Test test', 1)
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (3, N'Quiz III', N'TEST TEST', 0)
SET IDENTITY_INSERT [dbo].[Quiz] OFF
/****** Object: Table [dbo].[Employee] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Employee](
[Usename] [nvarchar](50) NOT NULL,
[Name] [varchar](50) NOT NULL,
[DivisionCode] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[Usename] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John12', N'John A', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John13', N'John B', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John15', N'John C', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Maria12', N'Maria A', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Rony14', N'Rony A', N'2')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tid52', N'Tid A', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tim12', N'Tim A', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tim15', N'Tim B', N'2')
/****** Object: Table [dbo].[UserQuiz] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserQuiz](
[UserQuizID] [int] IDENTITY(1,1) NOT NULL,
[QuizID] [int] NOT NULL,
[DateTimeComplete] [datetime] NOT NULL,
[Score] [float] NOT NULL,
[Username] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_UserQuiz] PRIMARY KEY CLUSTERED
(
[UserQuizID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[UserQuiz] ON
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (1, 1, CAST(0x0000A07900000000 AS DateTime), 100, N'John12')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (2, 1, CAST(0x0000A07900000000 AS DateTime), 50, N'Tim12')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (3, 1, CAST(0x0000A07B00000000 AS DateTime), 100, N'Rony14')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (4, 1, CAST(0x0000A07900000000 AS DateTime), 0, N'Tim15')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (5, 1, CAST(0x0000A07900000000 AS DateTime), 100, N'Tid52')
SET IDENTITY_INSERT [dbo].[UserQuiz] OFF
/****** Object: ForeignKey [FK_Employee_Divisions] Script Date: 08/03/2012 19:36:09 ******/
ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [FK_Employee_Divisions] FOREIGN KEY([DivisionCode])
REFERENCES [dbo].[Divisions] ([SapCode])
GO
ALTER TABLE [dbo].[Employee] CHECK CONSTRAINT [FK_Employee_Divisions]
GO
/****** Object: ForeignKey [FK_UserQuiz_Employee] Script Date: 08/03/2012 19:36:09 ******/
ALTER TABLE [dbo].[UserQuiz] WITH CHECK ADD CONSTRAINT [FK_UserQuiz_Employee] FOREIGN KEY([Username])
REFERENCES [dbo].[Employee] ([Usename])
GO
ALTER TABLE [dbo].[UserQuiz] CHECK CONSTRAINT [FK_UserQuiz_Employee]
GO
/****** Object: ForeignKey [FK_UserQuiz_Quiz] Script Date: 08/03/2012 19:36:09 ******/
ALTER TABLE [dbo].[UserQuiz] WITH CHECK ADD CONSTRAINT [FK_UserQuiz_Quiz] FOREIGN KEY([QuizID])
REFERENCES [dbo].[Quiz] ([QuizID])
GO
ALTER TABLE [dbo].[UserQuiz] CHECK CONSTRAINT [FK_UserQuiz_Quiz]
GO
UPDATE:
The results should be like this:
Division ************* Overall Percentage
A **************** 80
B **************** 60
C **************** 50
And the overall percentage is the total of all percent completion of each division in each quiz. For instance, the percent completion for division A in Quiz#1 = 40%, and in Quiz#2 = 60% and in Quiz#3 = 90%, the overall percentage that should be shown by this query is the total of all the of them divided by the total number of sent quizzes (which is 3). I hope I am clear and the concept is obvious.
UPDATE #2:
I am still struggling with it but I came up with a query that shows the total number of employees and participants in each quiz for each division. And here's the query:
SELECT COUNT(dbo.Employee.Usename) AS [Total Number of Employees], COUNT(dbo.UserQuiz.Username) AS [Total Number of Participants], dbo.Divisions.Division,
dbo.Quiz.Title
FROM dbo.Divisions INNER JOIN
dbo.Employee ON dbo.Divisions.SapCode = dbo.Employee.DivisionCode INNER JOIN
dbo.UserQuiz ON dbo.Employee.Usename = dbo.UserQuiz.Username INNER JOIN
dbo.Quiz ON dbo.UserQuiz.QuizID = dbo.Quiz.QuizID
WHERE (dbo.Quiz.IsSent = 1)
GROUP BY dbo.Divisions.Division, dbo.Quiz.Title
What should I do to improve it and get what I need?
The following query may do what you want. I calculates the number of employees in each division, multiplies this by the number of quizzes. It then divides the number actually taken by this total:
select de.Division, de.numemployees, de.numemployees*q.numquizzes as qe_combos,
numquizzestaken/1.0*de.numemployees*q.numquizzes as proportion
from (select d.Division, count(*) as numemployees
from Employee e join
Division d
on e.DivisionCode = d.SapCode
group by d.Division
) de left outer join
(select d.Division, count(*) as numquizzestaken
from Employee e join
Division d
on e.DivisionCode = d.SapCode join
UserQuiz uq
on e.UserName = uq.UserName join
Quiz q
on uq.QuidId = q.QuizId and
q.issent = true
group by de.Division
) dq
on de.division = dq.division cross join
(select count(*) as numquizes
from Quiz q
where isSent = true
) q

How to show the overall percentage of participation for each division?

I am a new web developer and I am developing a simple training management system which provides the users with quizzes. The system developed using ASP.NET and MS SQLServer. Now,
I need to come up with a query that shows the percentage of participation of each division in all the offered safety quizzes (which means quizzes with IsSent = true).
I have the following database design:
Employee Table: Username, Name, DivisionCode
Divisions Table: SapCode, Divison
Quiz Table: QuizID, Title, Description, IsSent
UserQuiz: UserQuizID, QuizID, DateTimeComplete, Username
(DivisionCode is a foreign key to the SapCode. IsSent is a flag to indicate to the quizzes that have been offered and sent to the users to participate in them.)
For example, If I have four divisions; A, B, C and D, and I have around 23 quizzes have been sent to the employees in those divisions. Since each division has a specific percentage of participation in each quiz. My query should show the overall percentage of participation in all offered quizzes for each division. So the result should not be broken down with respect to each quiz.
The desired result that I am looking for it:
Division ************* Overall Percentage
A **************** 80
B **************** 60
C **************** 50
And the overall percentage is the total of all percent completion of each division in each quiz. For instance, the percent completion for division A in Quiz#1 = 40%, and in Quiz#2 = 60% and in Quiz#3 = 90%, the overall percentage that should be shown by this query is the total of all the of them divided by the total number of sent quizzes (which is 3). I hope I am clear and the concept is obvious.
So how to do that?
And here's the schema of the database with its data:
USE [Test]
GO
/****** Object: Table [dbo].[Divisions] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Divisions](
[SapCode] [nvarchar](50) NOT NULL,
[Division] [varchar](50) NOT NULL,
CONSTRAINT [PK_Divisions] PRIMARY KEY CLUSTERED
(
[SapCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'1', N'A')
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'2', N'B')
INSERT [dbo].[Divisions] ([SapCode], [Division]) VALUES (N'3', N'C')
/****** Object: Table [dbo].[Quiz] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Quiz](
[QuizID] [int] IDENTITY(1,1) NOT NULL,
[Title] [varchar](50) NOT NULL,
[Description] [varchar](50) NOT NULL,
[IsSent] [bit] NOT NULL,
CONSTRAINT [PK_Quiz] PRIMARY KEY CLUSTERED
(
[QuizID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[Quiz] ON
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (1, N'Quiz I', N'Test', 1)
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (2, N'Quiz II', N'Test test', 1)
INSERT [dbo].[Quiz] ([QuizID], [Title], [Description], [IsSent]) VALUES (3, N'Quiz III', N'TEST TEST', 0)
SET IDENTITY_INSERT [dbo].[Quiz] OFF
/****** Object: Table [dbo].[Employee] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Employee](
[Usename] [nvarchar](50) NOT NULL,
[Name] [varchar](50) NOT NULL,
[DivisionCode] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[Usename] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John12', N'John A', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John13', N'John B', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'John15', N'John C', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Maria12', N'Maria A', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Rony14', N'Rony A', N'2')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tid52', N'Tid A', N'3')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tim12', N'Tim A', N'1')
INSERT [dbo].[Employee] ([Usename], [Name], [DivisionCode]) VALUES (N'Tim15', N'Tim B', N'2')
/****** Object: Table [dbo].[UserQuiz] Script Date: 08/03/2012 19:36:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[UserQuiz](
[UserQuizID] [int] IDENTITY(1,1) NOT NULL,
[QuizID] [int] NOT NULL,
[DateTimeComplete] [datetime] NOT NULL,
[Score] [float] NOT NULL,
[Username] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_UserQuiz] PRIMARY KEY CLUSTERED
(
[UserQuizID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[UserQuiz] ON
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (1, 1, CAST(0x0000A07900000000 AS DateTime), 100, N'John12')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (2, 1, CAST(0x0000A07900000000 AS DateTime), 50, N'Tim12')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (3, 1, CAST(0x0000A07B00000000 AS DateTime), 100, N'Rony14')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (4, 1, CAST(0x0000A07900000000 AS DateTime), 0, N'Tim15')
INSERT [dbo].[UserQuiz] ([UserQuizID], [QuizID], [DateTimeComplete], [Score], [Username]) VALUES (5, 1, CAST(0x0000A07900000000 AS DateTime), 100, N'Tid52')
SET IDENTITY_INSERT [dbo].[UserQuiz] OFF
/****** Object: ForeignKey [FK_Employee_Divisions] Script Date: 08/03/2012 19:36:09 ******/
ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [FK_Employee_Divisions] FOREIGN KEY([DivisionCode])
REFERENCES [dbo].[Divisions] ([SapCode])
GO
ALTER TABLE [dbo].[Employee] CHECK CONSTRAINT [FK_Employee_Divisions]
GO
/****** Object: ForeignKey [FK_UserQuiz_Employee] Script Date: 08/03/2012 19:36:09 ******/
ALTER TABLE [dbo].[UserQuiz] WITH CHECK ADD CONSTRAINT [FK_UserQuiz_Employee] FOREIGN KEY([Username])
REFERENCES [dbo].[Employee] ([Usename])
GO
ALTER TABLE [dbo].[UserQuiz] CHECK CONSTRAINT [FK_UserQuiz_Employee]
GO
/****** Object: ForeignKey [FK_UserQuiz_Quiz] Script Date: 08/03/2012 19:36:09 ******/
ALTER TABLE [dbo].[UserQuiz] WITH CHECK ADD CONSTRAINT [FK_UserQuiz_Quiz] FOREIGN KEY([QuizID])
REFERENCES [dbo].[Quiz] ([QuizID])
GO
ALTER TABLE [dbo].[UserQuiz] CHECK CONSTRAINT [FK_UserQuiz_Quiz]
GO
And here's the query:
SELECT COUNT(DISTINCT dbo.UserQuiz.Username) AS [Total Number of Participants], dbo.Divisions.DivisionShortcut, dbo.Quiz.Title
FROM dbo.employee INNER JOIN
dbo.UserQuiz ON dbo.employee.Username = dbo.UserQuiz.Username INNER JOIN
dbo.Quiz ON dbo.UserQuiz.QuizID = dbo.Quiz.QuizID INNER JOIN
dbo.Divisions ON dbo.employee.DivisionCode = dbo.Divisions.SapCode
WHERE (dbo.Quiz.IsSent = 1)
GROUP BY dbo.Divisions.DivisionShortcut, dbo.Quiz.Title, dbo.UserQuiz.QuizID
ORDER BY dbo.UserQuiz.QuizID DESC
What should I do to improve it and get what I need?

T-SQL get price between two dates

I am making a small database trading system and I have a problem with duplication which I am unsure how to solve. Basically I have a table with prices with the datetime which that price was set and I also have a table with the time a trade was made. I want to get the correct price based on trade datetime.
USE [a_trading_system]
GO
/****** Object: Table [dbo].[Trade] Script Date: 06/30/2012 14:49:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Trade](
[trade_id] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[trade_volume] [int] NOT NULL,
[trade_action] [varchar](5) NOT NULL,
[trade_date] [datetime] NOT NULL,
[timestap] [timestamp] NOT NULL,
[trader_id] [int] NOT NULL,
[exch_ticker] [varchar](8) NOT NULL,
CONSTRAINT [PK_Trades] PRIMARY KEY CLUSTERED
(
[trade_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Trade] WITH CHECK ADD CONSTRAINT [FK_Trade_Contract] FOREIGN KEY([exch_ticker])
REFERENCES [dbo].[Contract] ([exch_ticker])
GO
ALTER TABLE [dbo].[Trade] CHECK CONSTRAINT [FK_Trade_Contract]
GO
ALTER TABLE [dbo].[Trade] WITH CHECK ADD CONSTRAINT [FK_Trade_Trader] FOREIGN KEY([trader_id])
REFERENCES [dbo].[Trader] ([trader_id])
GO
ALTER TABLE [dbo].[Trade] CHECK CONSTRAINT [FK_Trade_Trader]
GO
ALTER TABLE [dbo].[Trade] ADD CONSTRAINT [DF_Trades_trade_id] DEFAULT (newid()) FOR [trade_id]
GO
USE [a_trading_system]
GO
/****** Object: Table [dbo].[Contract] Script Date: 06/30/2012 14:56:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Contract](
[exch_ticker] [varchar](8) NOT NULL,
[exch_name] [varchar](50) NULL,
[portfolio_id] [varchar](8) NOT NULL,
[region_cd] [varchar](5) NULL,
CONSTRAINT [PK_Contract] PRIMARY KEY CLUSTERED
(
[exch_ticker] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Contract] WITH CHECK ADD CONSTRAINT [FK_Contract_portfolio] FOREIGN KEY([portfolio_id])
REFERENCES [dbo].[portfolio] ([portfolio_id])
GO
ALTER TABLE [dbo].[Contract] CHECK CONSTRAINT [FK_Contract_portfolio]
GO
ALTER TABLE [dbo].[Contract] WITH CHECK ADD CONSTRAINT [FK_Contract_region] FOREIGN KEY([region_cd])
REFERENCES [dbo].[Region] ([region_cd])
GO
ALTER TABLE [dbo].[Contract] CHECK CONSTRAINT [FK_Contract_region]
GO
USE [a_trading_system]
GO
/****** Object: Table [dbo].[price_details] Script Date: 06/30/2012 14:58:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[price_details](
[price_id] [int] IDENTITY(1,1) NOT NULL,
[exch_ticker] [varchar](8) NOT NULL,
[price_set_date] [datetime] NOT NULL,
[buy_price] [decimal](7, 2) NOT NULL,
[sell_price] [decimal](7, 2) NOT NULL,
CONSTRAINT [PK_price_detail] PRIMARY KEY CLUSTERED
(
[price_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[price_details] WITH CHECK ADD CONSTRAINT [FK_price_details_Contract] FOREIGN KEY([exch_ticker])
REFERENCES [dbo].[Contract] ([exch_ticker])
GO
ALTER TABLE [dbo].[price_details] CHECK CONSTRAINT [FK_price_details_Contract]
GO
View
USE [a_trading_system]
GO
/****** Object: View [dbo].[V_all_uk] Script Date: 06/30/2012 14:39:18 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER VIEW [dbo].[V_all_uk]
AS
SELECT distinct
co.exch_ticker,
--co.region_cd,
po.portfolio_type,
r.region_name,
r.currency,
t.trade_id,
t.trade_volume,
t.trade_action,
t.trade_date,
pr.buy_price,
--(select distinct pr.buy_price from price_details pr
--where pr.price_set_date <= t.trade_date or pr.price_set_date >= t.trade_date) as price_details,
--MIN(t.trade_date) as trade_date,
--pr.buy_price,
--pr.sell_price,
--pr.price_set_date, --This is the cause of duplication
--pr.price_set_time,case when t.trade_date IS NOT NULL then
--case
--when t.trade_action = 'Buy' then
--t.trade_volume * max(pr.buy_price)
--else
--case when trade_action = 'Sell' then
--t.trade_volume * max(pr.sell_price)
--end
--end as 'trade_value' ,
tr.trader_name,
tr.trader_address,
tr.phone
FROM dbo.Contract as co
INNER JOIN dbo.Portfolio as po ON co.portfolio_id = po.portfolio_id
INNER JOIN dbo.region as r ON co.region_cd = r.region_cd
INNER JOIN dbo.Trade as t ON co.exch_ticker = t.exch_ticker
INNER JOIN dbo.trader as tr ON t.trader_id = tr.trader_id
inner join dbo.price_details as pr on pr.exch_ticker = t.exch_ticker
where r.region_cd = 'UK'
--group by
--co.exch_ticker,
--co.region_cd,
--po.portfolio_type,
--r.region_name,
--r.currency,
--t.trade_id,
--t.trade_volume,
--t.trade_action,
--pr.buy_price,
--pr.sell_price,
--tr.trader_name,
--tr.trader_address,
--tr.phone
GO
These are the three main tables if you need to see data as well just say because I don't usually post SQL questions on this website.
Explanation
If a price is set at 12:20 and the price is 100 then at 12:40 the price is 80. These are two date ranges. So if I buy at 12:30 then I am buying at the price of 100 because that is last price. I am also doing my joins in a view so I can see all data. I will post that now.
Thanks
To get the latest price prior to a particular trade date:
select buy_price, sell_price
from price_details
where exch_ticker = #exch_ticker and price_set_date =
( select max( price_set_date )
from price_details
where exch_ticker = #exch_ticker and price_set_date <= #trade_date )
You may want to add an index on exch_ticker/trade_date(desc) to price_details.
The following assumes SQL Server 2005 or later version.
The idea is first to join Trade and price_details filtering out prices whose times are greater than the corresponding trades' times:
SELECT ...
FROM dbo.Trade t
INNER JOIN dbo.price_details pr ON pr.exch_ticker = t.exch_ticker
The above will get you a row set where every trade has got all prices up to the time of the trade. Now just rank the prices and get the latest one:
WITH trade_prices AS (
SELECT
t.*, -- actually you might want to review the list
pr.price_set_date, -- of columns being pulled from the two tables
pr.buy_price,
pr.sell_price,
rnk = ROW_NUMBER() OVER (PARTITION BY t.trade_id ORDER BY pr.price_set_date DESC)
FROM dbo.Trade t
INNER JOIN dbo.price_details pr ON pr.exch_ticker = t.exch_ticker
)
SELECT *
FROM trade_prices
WHERE rnk = 1
To incorporate this into your view, you will only need to:
1) add the trade_prices CTE,
2) replace two joins, to Trade and to price_details, with a join to trade_prices,
3) add the trade_prices.rnk = 1 condition to the WHERE clause.
Of course, the trader table will now be joined to trade_prices instead of to Trade. And you will also need to change the table aliases pr and t in the view's select list to the one you choose to assign to trade_prices.