架构有点奇怪。我有两张桌子:
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 :(得分:1)
您的数据存储方式似乎存在问题。在您的示例中,所有'ConcertAtArena1'
,'ConcertAtArena2'
和'ConcertAtArena3'
都链接到您在Venues
表格中多次定义的同一地点。
为什么ConcertAtArena1'
的正确答案不是'Arena3'
的事件,因为场地的ID是相同的。你在名字上使用某种挑剔的逻辑吗?
我怀疑你应该将Arenas作为不同的场地存放,或者在你有价格的地方添加另一个子表,每个竞技场都是独一无二的。这是一个例子,我添加了一个名为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
使用此查询,您将获得'ConcertAtArena3'
平均价格为50且'Conference'
平均价格为NULL