2016-09-22 52 views
-1

该架构有点奇怪。我有两个表:SQL - 生成一个最便宜的选项列表

CREATE TABLE [dbo].[Events](
    [Id] [int] NOT NULL, 
    [Name] [varchar](50) NOT NULL, 
    [VenueId] [int] NULL 
) 

CREATE TABLE [dbo].[Venues](
    [Id] [int] NOT NULL, 
    [Name] [nvarchar](50) NOT NULL, 
    [AveragePrice] [int] NOT NULL 
) 

和数据是这样的:

insert into Venues (Id, Name, AveragePrice) VALUES 
    (1, 'Arena1', 100), 
    (1, 'Arena2', 200), 
    (1, 'Arena3', 50), 
    (2, 'Club1', 50), 
    (2, 'Club2', 150) 

insert into Events (Id, Name, VenueId) VALUES 
    (1, 'ConsertAtArena1', 1), 
    (2, 'ConsertAtArena2', 1), 
    (3, 'ConsertAtArena3', 1), 
    (2, 'Conference', NULL) 

我需要制作:'ConsertAtArena3', 'Conference'。对于具有相同VenueId的事件以及具有NULL VenueId的所有事件,这是最便宜的Venue选项。表格非常庞大,高达几百万行。什么是有效的SELECT来做到这一点?

数据库是SQL Server 2012 Standard。

+0

添加预期的结果也是如此。 – jarlh

+0

您只需要执行计划即可查看查询成本! – Ragul

+2

ConsertAtArena3是最便宜的*?所有三场音乐会都有相同的'venueId'参考,因此它们都具有相同的价格。 –

回答

1

看起来您存储数据的方式存在问题。在您的示例中,所有'ConcertAtArena1','ConcertAtArena2''ConcertAtArena3'链接到您在Venues表中多次定义的同一场所。

为什么不是正确答案'ConcertAtArena1'作为'Arena3'的事件,因为场地的ID是相同的。你在那里使用某种模糊的逻辑吗?

我怀疑你应该把Arenas作为不同的场地存放,或者增加另一个有你的价格的子表,并且每个竞技场都是独一无二的。此处,我添加了名为阿里纳斯额外的表的例子:

DECLARE @Events TABLE (
    [Id] [int] NOT NULL, 
    [Name] [varchar](50) NOT NULL, 
    [ArenaId] [int] NULL 
) 

DECLARE @Venues TABLE(
    [Id] [int] NOT NULL, 
    [Name] [nvarchar](50) NOT NULL 
) 

DECLARE @arenas TABLE(
    [Id] [int] NOT NULL, 
    [VenueId] INT NOT NULL, 
    [Name] [nvarchar](50) NOT NULL, 
    [AveragePrice] [int] NOT NULL 
) 


insert into @venues (id, name) values 
(1, 'Venue1'), 
(2, 'Venue2') 

insert into @arenas (Id, VenueId, Name, AveragePrice) VALUES 
    (1,1, 'Arena1', 100), 
    (2,1, 'Arena2', 200), 
    (3,1, 'Arena3', 50), 
    (4,2, 'Club1', 50), 
    (5,2, 'Club2', 150) 

insert into @Events (Id, Name, ArenaId) VALUES 
    (1, 'ConsertAtArena1', 1), 
    (2, 'ConsertAtArena2', 2), 
    (3, 'ConsertAtArena3', 3), 
    (4, 'Conference', NULL) 

;WITH ranked AS (
SELECT e.Id, a.AveragePrice, ROW_NUMBER() OVER (PARTITION BY a.VenueId ORDER BY a.AveragePrice) AS rn 
FROM @Events e 
LEFT OUTER JOIN @arenas a ON a.Id = e.ArenaId) 

SELECT e.id,e.name,r.AveragePrice FROM @Events e 
INNER JOIN ranked r ON r.Id = e.Id 
WHERE r.rn = 1 

与此查询you'l得到'ConcertAtArena3'平均价格50 'Conference'平均价格NULL

+0

我无法控制架构,它就是这样。 –

+0

我明白了,但正如我在答案的第一部分所解释的那样,您的数据没有一致性来检索该信息。 –

+0

感谢您的帮助Ionut,我很感激。我明白你的意思,我得考虑一下。 –