I have the following database design with repect to the Star schema:
alll table: ID, user_id, cat_id, qa_id
user table: user_id, name, department
category table: cat_id, cat_text, sub_cat_text
QA table: aq_id, q_id, answer_id
question table: q_id, q_text, sub_q_text
answer table: answer_id, text
I have to come up with a query that shows the total number of participants in each question including its subquesiont with all of its answers even if there is no participants in any one of these answers. Fortunately, I could be able to come up with a query that shows: question, sub-question, total number of participants in each answer. However, the problem now is with showing the department. If there is no participants in one of the answer, the department will be shown as NULL. So how to modify this?
My Query:
SELECT dbo.question.q_text, dbo.question.sub_q_text, COUNT(dbo.[user].user_id) AS Expr1, dbo.answer.text, dbo.[user].department
FROM dbo.alll INNER JOIN
dbo.category ON dbo.alll.cat_id = dbo.category.cat_id INNER JOIN
dbo.QA ON dbo.alll.qa_id = dbo.QA.aq_id INNER JOIN
dbo.[user] ON dbo.alll.user_id = dbo.[user].user_id INNER JOIN
dbo.question ON dbo.QA.q_id = dbo.question.q_id RIGHT OUTER JOIN
dbo.answer ON dbo.QA.answer_id = dbo.answer.answer_id
WHERE (dbo.[user].department = 'pmod') AND (dbo.question.q_text = 'q1') OR
(dbo.[user].department IS NULL)
GROUP BY dbo.answer.text, dbo.question.q_text, dbo.question.sub_q_text, dbo.[user].department
Here is the Script of the database:
USE [master]
GO
/****** Object: Database [survey2] Script Date: 05/22/2012 13:18:16 ******/
CREATE DATABASE [survey2] ON PRIMARY
( NAME = N'survey2', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\survey2.mdf' , SIZE = 2048KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'survey2_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\survey2_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [survey2] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [survey2].[dbo].[sp_fulltext_database] #action = 'enable'
end
GO
ALTER DATABASE [survey2] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [survey2] SET ANSI_NULLS OFF
GO
ALTER DATABASE [survey2] SET ANSI_PADDING OFF
GO
ALTER DATABASE [survey2] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [survey2] SET ARITHABORT OFF
GO
ALTER DATABASE [survey2] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [survey2] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [survey2] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [survey2] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [survey2] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [survey2] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [survey2] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [survey2] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [survey2] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [survey2] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [survey2] SET DISABLE_BROKER
GO
ALTER DATABASE [survey2] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [survey2] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [survey2] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [survey2] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [survey2] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [survey2] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [survey2] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [survey2] SET READ_WRITE
GO
ALTER DATABASE [survey2] SET RECOVERY SIMPLE
GO
ALTER DATABASE [survey2] SET MULTI_USER
GO
ALTER DATABASE [survey2] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [survey2] SET DB_CHAINING OFF
GO
USE [survey2]
GO
/****** Object: Table [dbo].[category] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[category](
[cat_id] [int] IDENTITY(1,1) NOT NULL,
[cat_text] [varchar](50) NOT NULL,
[sub_cat_text] [varchar](50) NULL,
CONSTRAINT [PK_category] PRIMARY KEY CLUSTERED
(
[cat_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
/****** Object: Table [dbo].[answer] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[answer](
[answer_id] [int] IDENTITY(1,1) NOT NULL,
[text] [varchar](50) NOT NULL,
CONSTRAINT [PK_answer] PRIMARY KEY CLUSTERED
(
[answer_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
/****** Object: Table [dbo].[user] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[user](
[user_id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[department] [varchar](50) NOT NULL,
CONSTRAINT [PK_user] PRIMARY KEY CLUSTERED
(
[user_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
/****** Object: Table [dbo].[question] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[question](
[q_id] [int] IDENTITY(1,1) NOT NULL,
[q_text] [varchar](50) NOT NULL,
[sub_q_text] [varchar](50) NULL,
CONSTRAINT [PK_question] PRIMARY KEY CLUSTERED
(
[q_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
/****** Object: Table [dbo].[QA] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[QA](
[aq_id] [int] IDENTITY(1,1) NOT NULL,
[q_id] [int] NOT NULL,
[answer_id] [int] NOT NULL,
CONSTRAINT [PK_QA] PRIMARY KEY CLUSTERED
(
[aq_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].[alll] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[alll](
[ID] [int] IDENTITY(1,1) NOT NULL,
[user_id] [int] NULL,
[cat_id] [int] NULL,
[qa_id] [int] NULL,
CONSTRAINT [PK_alll] 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: View [dbo].[showing number of participants in each Q] Script Date: 05/22/2012 13:18:18 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[showing number of participants in each Q]
AS
SELECT COUNT(dbo.question.q_id) AS Expr1, dbo.[user].department, dbo.category.cat_text, dbo.category.sub_cat_text, dbo.question.q_text
FROM dbo.alll INNER JOIN
dbo.answer ON dbo.alll.answer_id = dbo.answer.answer_id INNER JOIN
dbo.category ON dbo.alll.cat_id = dbo.category.cat_id INNER JOIN
dbo.question ON dbo.alll.q_id = dbo.question.q_id INNER JOIN
dbo.[user] ON dbo.alll.user_id = dbo.[user].user_id
GROUP BY dbo.[user].department, dbo.category.cat_text, dbo.category.sub_cat_text, dbo.question.q_text
GO
EXEC sys.sp_addextendedproperty #name=N'MS_DiagramPane1', #value=N'[0E232FF0-B466-11cf-A24F-00AA00A3EFFF, 1.00]
Begin DesignProperties =
Begin PaneConfigurations =
Begin PaneConfiguration = 0
NumPanes = 4
Configuration = "(H (1[40] 4[20] 2[20] 3) )"
End
Begin PaneConfiguration = 1
NumPanes = 3
Configuration = "(H (1 [50] 4 [25] 3))"
End
Begin PaneConfiguration = 2
NumPanes = 3
Configuration = "(H (1 [50] 2 [25] 3))"
End
Begin PaneConfiguration = 3
NumPanes = 3
Configuration = "(H (4 [30] 2 [40] 3))"
End
Begin PaneConfiguration = 4
NumPanes = 2
Configuration = "(H (1 [56] 3))"
End
Begin PaneConfiguration = 5
NumPanes = 2
Configuration = "(H (2 [66] 3))"
End
Begin PaneConfiguration = 6
NumPanes = 2
Configuration = "(H (4 [50] 3))"
End
Begin PaneConfiguration = 7
NumPanes = 1
Configuration = "(V (3))"
End
Begin PaneConfiguration = 8
NumPanes = 3
Configuration = "(H (1[56] 4[18] 2) )"
End
Begin PaneConfiguration = 9
NumPanes = 2
Configuration = "(H (1 [75] 4))"
End
Begin PaneConfiguration = 10
NumPanes = 2
Configuration = "(H (1[66] 2) )"
End
Begin PaneConfiguration = 11
NumPanes = 2
Configuration = "(H (4 [60] 2))"
End
Begin PaneConfiguration = 12
NumPanes = 1
Configuration = "(H (1) )"
End
Begin PaneConfiguration = 13
NumPanes = 1
Configuration = "(V (4))"
End
Begin PaneConfiguration = 14
NumPanes = 1
Configuration = "(V (2))"
End
ActivePaneConfig = 0
End
Begin DiagramPane =
Begin Origin =
Top = 0
Left = 0
End
Begin Tables =
Begin Table = "alll"
Begin Extent =
Top = 61
Left = 226
Bottom = 178
Right = 386
End
DisplayFlags = 280
TopColumn = 0
End
Begin Table = "answer"
Begin Extent =
Top = 182
Left = 0
Bottom = 269
Right = 160
End
DisplayFlags = 280
TopColumn = 0
End
Begin Table = "category"
Begin Extent =
Top = 36
Left = 426
Bottom = 138
Right = 586
End
DisplayFlags = 280
TopColumn = 0
End
Begin Table = "question"
Begin Extent =
Top = 189
Left = 427
Bottom = 291
Right = 587
End
DisplayFlags = 280
TopColumn = 0
End
Begin Table = "user"
Begin Extent =
Top = 45
Left = 0
Bottom = 147
Right = 160
End
DisplayFlags = 280
TopColumn = 0
End
End
End
Begin SQLPane =
End
Begin DataPane =
Begin ParameterDefaults = ""
End
Begin ColumnWidths = 9
Width = 284
Width = 2265
Width = 1500
Width = 1500
Width = 1500
Width = 1500
Width = 1500
Width = 1500
Width = 1500
End
End
Begin CriteriaPane =
Begin ColumnWidths = 12
Column = 1440
Alias = 900
Table' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'VIEW',#level1name=N'showing number of participants in each Q'
GO
EXEC sys.sp_addextendedproperty #name=N'MS_DiagramPane2', #value=N' = 1170
Output = 720
Append = 1400
NewValue = 1170
SortType = 1350
SortOrder = 1410
GroupBy = 1350
Filter = 1350
Or = 1350
Or = 1350
Or = 1350
End
End
End
' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'VIEW',#level1name=N'showing number of participants in each Q'
GO
EXEC sys.sp_addextendedproperty #name=N'MS_DiagramPaneCount', #value=2 , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'VIEW',#level1name=N'showing number of participants in each Q'
GO
/****** Object: ForeignKey [FK_QA_answer] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[QA] WITH CHECK ADD CONSTRAINT [FK_QA_answer] FOREIGN KEY([answer_id])
REFERENCES [dbo].[answer] ([answer_id])
GO
ALTER TABLE [dbo].[QA] CHECK CONSTRAINT [FK_QA_answer]
GO
/****** Object: ForeignKey [FK_QA_question] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[QA] WITH CHECK ADD CONSTRAINT [FK_QA_question] FOREIGN KEY([q_id])
REFERENCES [dbo].[question] ([q_id])
GO
ALTER TABLE [dbo].[QA] CHECK CONSTRAINT [FK_QA_question]
GO
/****** Object: ForeignKey [FK_alll_category] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[alll] WITH CHECK ADD CONSTRAINT [FK_alll_category] FOREIGN KEY([cat_id])
REFERENCES [dbo].[category] ([cat_id])
GO
ALTER TABLE [dbo].[alll] CHECK CONSTRAINT [FK_alll_category]
GO
/****** Object: ForeignKey [FK_alll_QA] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[alll] WITH CHECK ADD CONSTRAINT [FK_alll_QA] FOREIGN KEY([qa_id])
REFERENCES [dbo].[QA] ([aq_id])
GO
ALTER TABLE [dbo].[alll] CHECK CONSTRAINT [FK_alll_QA]
GO
/****** Object: ForeignKey [FK_alll_user] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[alll] WITH CHECK ADD CONSTRAINT [FK_alll_user] FOREIGN KEY([user_id])
REFERENCES [dbo].[user] ([user_id])
GO
ALTER TABLE [dbo].[alll] CHECK CONSTRAINT [FK_alll_user]
GO
This is a query I think you are looking for. It first cross-joins users and questions. Now that there are all possible combinations between the two you may start counting matching answers.
EDIT: changed join to answer to cross join to be able to count 0s.
SELECT
dbo.[user].department,
dbo.question.q_text,
dbo.question.sub_q_text,
dbo.answer.text,
COUNT(qa.answer_id) AS Users_Answered
FROM [user]
CROSS JOIN question
CROSS JOIN answer
LEFT JOIN alll
ON [user].User_ID = alll.User_ID
LEFT JOIN qa
ON alll.qa_id = qa.aq_id
AND question.q_id = qa.q_id
AND qa.answer_id = answer.answer_id
GROUP BY
dbo.[user].department,
dbo.question.q_text,
dbo.question.sub_q_text,
dbo.answer.text
ORDER BY 1, 2
You might check it # Sql Fiddle.
New version of query # Sql Fiddle.
Related
I have got 3 columns:
[OldContent] [xml] NULL
[NewContent] [xml] NULL
[OldContent] [xml] NULL
I want to compare the data in two columns. I want to write the results into the third column ([OldContent])
How can I do it in SQL Server?
[OldContent] [xml] NULL, in
Value
<row GUEST_ID="13" GUEST_NAME="VEDAT" GUEST_SURNAME="PALA" ADRESS="IZMIR" />
[NewContent] [xml] NULL, in value
<row GUEST_ID="13" GUEST_NAME="VEDAT35" GUEST_SURNAME="PALA" ADRESS="IZMIR" CITY="DR" CITY_CODE="35" />
I want to write the value in it.
[UpdateContent] [xml] NULL
<row GUEST_NAME="VEDAT35 CITY="DR" CITY_CODE="35" />
I need a procedure to compare XML column values.
It is quite easy to get the data out of XML. Then you may compare your data "as ever". The result you can write out into a new XML with "FOR XML".
Try it like this:
DECLARE #myXML XML=
'<rows>
<row GUEST_ID="13" GUEST_NAME="VEDAT35" GUEST_SURNAME="PALA" ADRESS="IZMIR" CITY="DR" CITY_CODE="35" />
<row GUEST_ID="14" GUEST_NAME="TestGuestName" GUEST_SURNAME="TestSurname" ADRESS="TestAddr" CITY="TestCity" CITY_CODE="11" />
</rows>';
--This is how you retrieve the data
SELECT x.y.value('#GUEST_ID','int')
,x.y.value('#GUEST_NAME','varchar(max)')
,x.y.value('#GUEST_SURNAME','varchar(max)')
,x.y.value('#ADRESS','varchar(max)')
,x.y.value('#CITY','varchar(max)')
,x.y.value('#CITY_CODE','int')
FROM #myXML.nodes('/rows/row') AS x(y)
--This is how you create a new XML with your data
SELECT 13 AS [#GUEST_ID]
,'NewName' AS [#GUEST_NAME]
,'NewSurname' AS [#GUEST_SURNAME]
,'NewAddr' AS [#GUEST_ADRESS]
,'NewCity' AS [#CITY]
,12 AS [#CITY_CODE]
FOR XML PATH('row'),ROOT('rows')
samples table
USE [DENEME]
GO
/****** Object: Table [dbo].[GUESTS] Script Date: 17.07.2015 22:19:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[GUESTS](
[GUEST_ID] [int] IDENTITY(1,1) NOT NULL,
[GUEST_NAME] [varchar](50) NULL,
[GUEST_SURNAME] [varchar](50) NULL,
[ADRESS] [varchar](100) NULL,
[CITY] [varchar](50) NULL,
[CITY_CODE] [varchar](10) NULL,
[COUNTRY] [varchar](50) NULL,
[STATUS] [varchar](20) NULL,
[COMMENT] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED
(
[GUEST_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
SET ANSI_PADDING OFF
GO
USE [DENEME]
GO
/****** Object: Trigger [dbo].[iudt_AutoAuditChanges] Script Date: 17.07.2015 22:20:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[iudt_AutoAuditChanges]
ON [dbo].[GUESTS]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
SET NOCOUNT ON;
declare #AuditType char(1) /* BEN EKELEDM*/
Declare #v_AuditID bigint
/******************************/
if exists (select * from inserted)
if exists (select * from deleted)
SET #AuditType = 'U'
else
SET #AuditType = 'I'
else
SET #AuditType = 'D'
/******************************/
IF OBJECT_ID('dbo.AutoAudit','U') IS NULL BEGIN
CREATE TABLE [dbo].[AutoAudit]
( [AuditID] bigint identity,
[AuditType] Char(1),
[AuditDate] DateTime,
[AuditUserName] varchar(128),
[TableName] varchar(128) NULL,
[OldContent] XML NULL,
[NewContent] XML NULL,
[Updatedcontent] XML NULL
)
ALTER TABLE dbo.AutoAudit ADD CONSTRAINT
PK_AutoAudit PRIMARY KEY CLUSTERED
(
[AuditID]
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [idx_AutoAudit_TableName_AuditDate] ON [dbo]. [AutoAudit]
( [TableName] ASC,
[AuditDate] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
END
Select * Into #AuditDeleted from deleted
Select * Into #AuditInserted from inserted
While (Select COUNT(*) from #AuditDeleted) > 0 OR (Select COUNT(*) from #AuditInserted) > 0
Begin
INSERT INTO [dbo].[AutoAudit]
( [AuditDate],[AuditType], [AuditUserName], [TableName], [OldContent], [NewContent])
SELECT
GETDATE(),
#AuditType,
SUSER_NAME(),
[TableName]=object_name([parent_obj]),
[OldContent]=CAST((SELECT TOP 1 * FROM #AuditDeleted D FOR XML RAW) AS xml),
[NewContent]=CAST((SELECT TOP 1 * FROM #AuditInserted I FOR XML RAW) AS xml)
FROM sysobjects
WHERE
[xtype] = 'tr'
and [name] = OBJECT_NAME(##PROCID)
Set #v_AuditID = SCOPE_IDENTITY()
Delete from AutoAudit
Where AuditID = #v_AuditID
AND Convert(varchar(max),oldContent) = Convert(varchar(max),NewContent)
Delete top(1) from #AuditDeleted
Delete top(1) from #AuditInserted
End
END
I am writing log program.
OldContent:
<row GUEST_ID="19" GUEST_NAME="VEDAT" GUEST_SURNAME="PALA" ADRESS="TURKEY" CITY="TOKAT" CITY_CODE="60" />
newcontent:
<row GUEST_ID="19" GUEST_NAME="VEDAT60" GUEST_SURNAME="PALA" ADRESS="TURKEY" CITY="TOKAT" CITY_CODE="60" STATUS="other" COMMENT="uptaded fields" />
Expected results:
UptadedContent:
<row GUEST_NAME="VEDAT60" STATUS="other" COMMENT="uptaded fields" />
I want compare procedure..
Look this picture
IMG]http://i59.tinypic.com/24nfibl.png[/IMG]
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
;
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.
I am trying to write a query where for each day I get the minimum and maximum price for each item from price details table.
In price details table prices are set multiple times a day so there are many records for the same date. So I want a table where there is one row for each date and then join that table to the same table so for each distinct date I want the minimum and maximum value.
USE [a_trading_system]
GO
/****** Object: Table [dbo].[price_details] Script Date: 07/01/2012 17:28:31 ******/
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
SQL Query
select distinct
substring(convert(varchar(12),p1.price_set_date), 0, 12),
p2.exch_ticker,
(select MIN(buy_price) from price_details ),
(select MAX(buy_price) from price_details )
from price_details as p1
left join price_details as p2 on p2.exch_ticker = p1.exch_ticker
where p1.exch_ticker = p2.exch_ticker
group by p1.price_set_date, p2.exch_ticker
Summary
Table has many prices set on the same day. Want min and max values for each day for each exch ticker.
Thanks
A simple group by should work:
select cast(price_set_date as date) as [Date]
, exch_ticker
, min(buy_price) as MinPrice
, max(buy_price) as MaxPrice
from price_details as p
group by
exch_ticker
, cast(price_set_date as date)
Not sure why your example query is using a self join. If there's a good reason please add an explanation to your question.
I have a table called ApprovalTasks... Approvals has a status column
I also have a view called ApprovalsView
When I try a straight update :
update ApprovalTasks set Status = 2 where ApprovalTaskID = 48
I'm getting this error message:
Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.ApprovalsView' with unique index 'IX_ApprovalTaskID'.
The statement has been terminated.
Any idea why this is happening?
Here is the create table script:
USE [CSPMOSSApplication]
GO
/****** Object: Table [dbo].[ApprovalTasks] Script Date: 12/11/2008 12:41:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ApprovalTasks](
[ApprovalTaskID] [int] IDENTITY(1,1) NOT NULL,
[ApproverID] [int] NOT NULL,
[DueDate] [datetime] NULL,
[Status] [smallint] NOT NULL,
[ApprovedRejectedDate] [datetime] NULL,
[Reason] [nvarchar](1024) COLLATE Finnish_Swedish_CI_AS NULL,
[OrganizationID] [int] NOT NULL,
[TicketID] [int] NOT NULL,
[Link] [nchar](255) COLLATE Finnish_Swedish_CI_AS NULL,
[GlobalApproverID] [int] NULL,
CONSTRAINT [PK_Approval_Tasks] PRIMARY KEY CLUSTERED
(
[ApprovalTaskID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
USE [CSPMOSSApplication]
GO
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_ApprovalTaskStatuses] FOREIGN KEY([Status])
REFERENCES [dbo].[ApprovalTaskStatuses] ([ApprovalTaskStatusID])
GO
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_ApprovalTaskStatuses]
GO
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Organizations] FOREIGN KEY([OrganizationID])
REFERENCES [dbo].[Organizations] ([OrganizationID])
GO
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Organizations]
GO
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Tickets] FOREIGN KEY([TicketID])
REFERENCES [dbo].[Tickets] ([TicketID])
GO
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Tickets]
GO
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Users] FOREIGN KEY([ApproverID])
REFERENCES [dbo].[Users] ([UserID])
GO
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Users]
PK_Approval_Tasks(Clustered)
USE [CSPMOSSApplication]
GO
/****** Object: Index [PK_Approval_Tasks] Script Date: 12/11/2008 12:45:50 ******/
ALTER TABLE [dbo].[ApprovalTasks] ADD CONSTRAINT [PK_Approval_Tasks] PRIMARY KEY CLUSTERED
(
[ApprovalTaskID] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
IX_ApprovalTaskID(Clsutered)
SE [CSPMOSSApplication]
GO
SET ARITHABORT ON
GO
SET CONCAT_NULL_YIELDS_NULL ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
SET ANSI_PADDING ON
GO
SET ANSI_WARNINGS ON
GO
SET NUMERIC_ROUNDABORT OFF
GO
/****** Object: Index [IX_ApprovalTaskID] Script Date: 12/11/2008 12:47:27 ******/
CREATE UNIQUE CLUSTERED INDEX [IX_ApprovalTaskID] ON [dbo].[ApprovalsView]
(
[ApprovalTaskID] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
Create View Script
USE [CSPMOSSApplication]
GO
-- =============================================
-- Script Template
-- =============================================
-- [ApprovalTasks]: add columns Link, GlobalApproverID
IF NOT EXISTS(SELECT 1 FROM sysobjects,syscolumns WHERE sysobjects.id = syscolumns.id
AND sysobjects.name = 'ApprovalTasks' AND syscolumns.name = 'Link')
BEGIN
ALTER TABLE ApprovalTasks ADD [Link] [nchar] (255) COLLATE Finnish_Swedish_CI_AS NULL
PRINT 'Column ApprovalTasks.Link was added.'
END
IF NOT EXISTS(SELECT 1 FROM sysobjects,syscolumns WHERE sysobjects.id = syscolumns.id
AND sysobjects.name = 'ApprovalTasks' AND syscolumns.name = 'GlobalApproverID')
BEGIN
ALTER TABLE ApprovalTasks ADD [GlobalApproverID] [int] NULL
PRINT 'Column ApprovalTasks.GlobalApproverID was added.'
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_GlobalApproverID] FOREIGN KEY([GlobalApproverID])
REFERENCES [dbo].[Users] ([UserID])
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_GlobalApproverID]
END
-- [ApprovalsView]
IF EXISTS (SELECT * FROM sys.fulltext_indexes fti WHERE fti.object_id = OBJECT_ID(N'[dbo].[ApprovalsView]'))
BEGIN
DROP FULLTEXT INDEX ON [dbo].[ApprovalsView]
PRINT 'FULLTEXT INDEX on [ApprovalsView] was dropped.'
END
GO
IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[ApprovalsView]') AND name = N'IX_ApprovalTaskID')
BEGIN
DROP INDEX IX_ApprovalTaskID ON [dbo].[ApprovalsView] WITH ( ONLINE = OFF )
PRINT 'INDEX IX_ApprovalTaskID was dropped.'
END
GO
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[ApprovalsView]'))
DROP VIEW [dbo].[ApprovalsView]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[ApprovalsView]
WITH SCHEMABINDING
AS
SELECT at.ApprovalTaskID,
at.ApproverID,
at.DueDate,
at.Status,
ats.ApprovalTaskStatusTranslationKey AS StatusText,
at.ApprovedRejectedDate,
at.Reason,
at.OrganizationID,
ord.Name AS OrderName,
ord.TotalPrice,
ord.SubmitDate,
ord.OrdererID,
usr.FirstName AS OrdererFirstName,
usr.LastName AS OrdererLastName,
ordi.Items_Name AS ItemName,
ordi.Items_Description AS ItemDescription,
ordi.OtherInformation AS ItemInformation,
oir.RecipientFullName,
CONVERT(nvarchar(250), oir.DeliveryAddress) As DeliveryAddress,
ti.Description
FROM dbo.ApprovalTasks at
INNER JOIN
dbo.ApprovalTaskStatuses ats ON ats.ApprovalTaskStatusID = at.Status
INNER JOIN
dbo.Orders_Items_Recipients oir ON oir.TicketID = at.TicketID
INNER JOIN
dbo.Orders_Items ordi ON ordi.Orders_ItemsID = oir.Orders_ItemsID
INNER JOIN
dbo.Orders ord ON ordi.OrderID = ord.OrderID
INNER JOIN
dbo.Users usr ON ord.OrdererID = usr.UserID
INNER JOIN
dbo.Tickets ti ON ti.TicketID = at.TicketID
GO
CREATE UNIQUE CLUSTERED INDEX [IX_ApprovalTaskID] ON [dbo].[ApprovalsView]
(
[ApprovalTaskID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
GO
CREATE FULLTEXT INDEX ON [dbo].[ApprovalsView](
[DeliveryAddress] LANGUAGE [Neutral],
[ItemDescription] LANGUAGE [Neutral],
[ItemInformation] LANGUAGE [Neutral],
[ItemName] LANGUAGE [Neutral],
[OrdererFirstName] LANGUAGE [Neutral],
[OrdererLastName] LANGUAGE [Neutral],
[OrderName] LANGUAGE [Neutral],
[Reason] LANGUAGE [Neutral],
[RecipientFullName] LANGUAGE [Neutral])
KEY INDEX [IX_ApprovalTaskID] ON [ApprovalSearchCatalog]
WITH CHANGE_TRACKING AUTO
GO
ALTER FULLTEXT CATALOG [ApprovalSearchCatalog] rebuild
PRINT 'Catalog [ApprovalSearchCatalog] task to rebuild fulltext index was sent.'
-- STORED PROCEDURES
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ReceiveApprovalTasksFromQueue]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[ReceiveApprovalTasksFromQueue]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
EXEC dbo.sp_executesql #statement = N'
-- =============================================
-- Author: Petr Klozik
-- Create date: 19.11.2008
-- Description: Gets approvals which DueDate is over ReferenceDate (now)
-- =============================================
CREATE Procedure [dbo].[ReceiveApprovalTasksFromQueue]
#Limit int
As
BEGIN
SET NOCOUNT ON;
If Not #Limit Is Null Set RowCount #Limit
-- Status: WaitingForApproval = 1
Select Tasks.ApprovalTaskID
From ApprovalTasks Tasks
Where Status = 1 And DueDate < GetDate()
END
'
GO
GRANT EXECUTE ON [dbo].[ReceiveApprovalTasksFromQueue] TO [OMT_IntegrationRole]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[UpdateApprovalTaskInfo]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[UpdateApprovalTaskInfo]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
EXEC dbo.sp_executesql #statement = N'
-- =============================================
-- Author: Klozik Petr
-- Create date: 2008-11-25
-- Description: Updates Approval task info to DB
-- =============================================
CREATE PROCEDURE [dbo].[UpdateApprovalTaskInfo]
#ApprovalTaskID int,
#DueDate datetime,
#ApprovalRejectDate datetime,
#Reason nvarchar(1024),
#Status int,
#GlobalApproverID int
AS
BEGIN
SET NOCOUNT ON;
Update ApprovalTasks
Set DueDate = #DueDate,
ApprovedRejectedDate = #ApprovalRejectDate,
Reason = #Reason,
Status = #Status,
GlobalApproverID = #GlobalApproverID
Where ApprovalTaskID = #ApprovalTaskID
END
'
GO
GRANT EXECUTE ON [dbo].[UpdateApprovalTaskInfo] TO [OMT_IntegrationRole]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetUserById]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[GetUserById]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
EXEC dbo.sp_executesql #statement = N'
-- =============================================
-- Author: Klozik Petr
-- Create date: 2008-12-04
-- Description: Gets user row by the specified ID.
-- =============================================
CREATE PROCEDURE [dbo].[GetUserById]
(
#UserID int
)
AS
BEGIN
SELECT
UserID,
RTRIM(SID) [SID],
RTRIM(OMTGUID) [OMTGUID],
RTRIM(UserAccount) [UserAccount],
RTRIM(Email) [Email],
RTRIM(FirstName) [FirstName],
RTRIM(LastName) [LastName],
RTRIM(Country) [Country],
RTRIM(City) [City],
RTRIM(PostalNumber) [PostalNumber],
RTRIM(StreetAddress) [StreetAddress],
RTRIM(PhoneNumber) PhoneNumber,
Modified,
Deleted,
Uploaded,
UploadCode,
UploadStatus,
RTRIM(Users.ADUserAccount) AS ADUserAccount
FROM
[dbo].[Users]
WHERE
UserID = #UserID
END
'
GO
GRANT EXECUTE ON [dbo].[GetUserById] TO [OMT_IntegrationRole]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetApprovalTaskInfoById]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[GetApprovalTaskInfoById]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
EXEC dbo.sp_executesql #statement = N'
-- =============================================
-- Author: Petr Klozik
-- Create date: 19.11.2008
-- Description: Gets approvals which DueDate is over ReferenceDate (now)
-- =============================================
CREATE Procedure [dbo].[GetApprovalTaskInfoById]
#ApprovalTaskID int
As
BEGIN
SET NOCOUNT ON;
Declare #OrganizationID int
Declare #CurrentApproverID int
Declare #NewApproverID int
Declare #NewOrganizationID int
Select #OrganizationID = OrganizationID, #CurrentApproverID = ApproverID
From ApprovalTasks
Where ApprovalTaskID = #ApprovalTaskID
Set #NewApproverID = (
Select Top 1 o.GlobalApproverID
From Organizations o
Inner Join OrganizationDescendants od On od.OrganizationID = o.OrganizationID
Where od.DescendantID = #OrganizationID
And Not(o.GlobalApproverID Is Null)
Order By o.OrganizationLevel Desc
)
If Not(#NewApproverID Is Null)
Begin
Set #NewOrganizationID = (
Select OrganizationID
from Organizations
Where GlobalApproverID = #NewApproverID)
End
Select Tasks.*, Tickets.Description AS TicketDescription,
Tickets.RequestorID, Tickets.OrdererID,
#NewApproverID AS OrgGlobalApproverID,
#NewOrganizationID AS OrgGlobalApproverOrganizationID
From ApprovalTasks Tasks
inner join Tickets Tickets on Tasks.TicketID = Tickets.TicketID
Where ApprovalTaskID = #ApprovalTaskID
END
'
GO
GRANT EXECUTE ON [dbo].[GetApprovalTaskInfoById] TO [OMT_IntegrationRole]
GO
Lucky guess: any update triggers defined?
2nd lucky guess: ApprovalsView is an indexed view whose index is violated after updating the ApprovalTask table.
look at the definition of the index IX_ApprovalTaskID
Is it possible there is a unique key constraint on ApprovalTaskID, StatusID which would mean there is another row in the table with Status = 2 & ApprovalTaskID = 48
I agree with user Learning, it looks like there's a FOR UPDATE trigger on ApprovalTasks that is inserting an ApprovalTaskID into ApprovalView
Try running DISABLE TRIGGER ALL ON ApprovalTasks and re-run the update
Since the error is coming from the object dbo.ApprovalsView , the problem is with a trigger on ApprovalsTask which is trying to update that table. I really think that ApprovalsView is a table and not a view. But you must have already checked for that.
It looks like a view has been created which is either of, or includes, the table you are updating and that the error occurs when the view is being updated with the changes.
Perhaps the view contains data from different tables which is incompatible, or has stricter constraints set?