MSSQL:使用不带 GROUP BY 子句的 DISTINCT、TOP 选择
MSSQL: use DISTINCT, TOP selection without a GROUP BY clause
我想使用不带 GROUP BY 子句的 DISTINCT 和 TOP selection。
我想要 select 来自 [locations] 的行,并按与 [location_photos]
中每个位置关联的行数对结果进行排序
我现在有了这个(甚至没有使用 TOP):
SELECT distinct(l.id),count(lp.locationid) OVER(partition by l.id) AS photos
,ISNULL(lp.locpath,'') as thumb
,l.id,l.title
FROM locations l
LEFT JOIN location_photos lp on lp.locationid=l.id
ORDER BY photos desc
但是 returns [location_photos] 中的每一行对应一行 (56,000),其中这应该是 [locations] 中行数的潜在最大值 (12,000)。
我已经检查过 here and here。
如何使用 DISTINCT 和 TOP select 不同的行数?
DDL 和数据
CREATE TABLE [dbo].[locations](
[id] [int] NOT NULL,
[title] [nvarchar](500) NOT NULL,
[createdate] [datetime] NULL,
CONSTRAINT [PK_locs] PRIMARY KEY NONCLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[locations] ADD CONSTRAINT [DF_homes_createdate] DEFAULT (getdate()) FOR [createdate]
GO
CREATE TABLE [dbo].[location_photos](
[id] [int] IDENTITY(1,1) NOT NULL,
[locationid] [int] NOT NULL,
[locpath] [nvarchar](250) NOT NULL,
CONSTRAINT [PK_location_photos] PRIMARY KEY NONCLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[location_photos] WITH CHECK ADD CONSTRAINT [FK_locs_photos_homes] FOREIGN KEY([locationid])
REFERENCES [dbo].[locations] ([id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[location_photos] CHECK CONSTRAINT [FK_locs_photos_homes]
GO
INSERT INTO [locations](id,title) VALUES (1,'new york')
INSERT INTO [locations](id,title) VALUES (2,'boston')
INSERT INTO [locations](id,title) VALUES (3,'chicago')
INSERT INTO [locations](id,title) VALUES (4,'los angeles')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc1')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc2')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc3')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc4')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc5')
INSERT INTO [location_photos](locationid,locpath) VALUES (2,'boston1')
INSERT INTO [location_photos](locationid,locpath) VALUES (2,'boston2')
INSERT INTO [location_photos](locationid,locpath) VALUES (2,'boston3')
INSERT INTO [location_photos](locationid,locpath) VALUES (2,'boston4')
--there are not photos for chicago on purpose
INSERT INTO [location_photos](locationid,locpath) VALUES (4,'la1')
INSERT INTO [location_photos](locationid,locpath) VALUES (4,'la2')
我想你想要聚合:
SELECT l.id, count(lp.locationid) AS cnt_photos, l.title
FROM locations l
LEFT JOIN location_photos lp on lp.locationid = l.id
GROUP BY l.id, l.title
ORDER BY cnt_photos desc
或者,您可以使用子查询来计算匹配的照片。这是使用横向连接执行此操作的一种方法:
select l.*, lp.*
from locations l
cross apply (select count(*) cnt_photos from location_photos lp where lp.locationid = l.id) lp
ORDER BY lp.cnt_photos desc
I want to select rows from [locations] and order the results by the number of rows are associated with each location in [location_photos]
您可以在 ORDER BY
子句中使用相关子查询:
select l.*
from locations l
order by (select count(*)
from location_photos lp
where lp.location_id = l.id
) desc;
如果您想要查询中的计数以及排序标准,只需将子查询移动到 select
:
select l.*,
(select count(*)
from location_photos lp
where lp.location_id = l.id
) as num_photos
from locations l
order by num_photos desc;
我想使用不带 GROUP BY 子句的 DISTINCT 和 TOP selection。
我想要 select 来自 [locations] 的行,并按与 [location_photos]
中每个位置关联的行数对结果进行排序我现在有了这个(甚至没有使用 TOP):
SELECT distinct(l.id),count(lp.locationid) OVER(partition by l.id) AS photos
,ISNULL(lp.locpath,'') as thumb
,l.id,l.title
FROM locations l
LEFT JOIN location_photos lp on lp.locationid=l.id
ORDER BY photos desc
但是 returns [location_photos] 中的每一行对应一行 (56,000),其中这应该是 [locations] 中行数的潜在最大值 (12,000)。
我已经检查过 here and here。
如何使用 DISTINCT 和 TOP select 不同的行数?
DDL 和数据
CREATE TABLE [dbo].[locations](
[id] [int] NOT NULL,
[title] [nvarchar](500) NOT NULL,
[createdate] [datetime] NULL,
CONSTRAINT [PK_locs] PRIMARY KEY NONCLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[locations] ADD CONSTRAINT [DF_homes_createdate] DEFAULT (getdate()) FOR [createdate]
GO
CREATE TABLE [dbo].[location_photos](
[id] [int] IDENTITY(1,1) NOT NULL,
[locationid] [int] NOT NULL,
[locpath] [nvarchar](250) NOT NULL,
CONSTRAINT [PK_location_photos] PRIMARY KEY NONCLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[location_photos] WITH CHECK ADD CONSTRAINT [FK_locs_photos_homes] FOREIGN KEY([locationid])
REFERENCES [dbo].[locations] ([id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[location_photos] CHECK CONSTRAINT [FK_locs_photos_homes]
GO
INSERT INTO [locations](id,title) VALUES (1,'new york')
INSERT INTO [locations](id,title) VALUES (2,'boston')
INSERT INTO [locations](id,title) VALUES (3,'chicago')
INSERT INTO [locations](id,title) VALUES (4,'los angeles')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc1')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc2')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc3')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc4')
INSERT INTO [location_photos](locationid,locpath) VALUES (1,'nyc5')
INSERT INTO [location_photos](locationid,locpath) VALUES (2,'boston1')
INSERT INTO [location_photos](locationid,locpath) VALUES (2,'boston2')
INSERT INTO [location_photos](locationid,locpath) VALUES (2,'boston3')
INSERT INTO [location_photos](locationid,locpath) VALUES (2,'boston4')
--there are not photos for chicago on purpose
INSERT INTO [location_photos](locationid,locpath) VALUES (4,'la1')
INSERT INTO [location_photos](locationid,locpath) VALUES (4,'la2')
我想你想要聚合:
SELECT l.id, count(lp.locationid) AS cnt_photos, l.title
FROM locations l
LEFT JOIN location_photos lp on lp.locationid = l.id
GROUP BY l.id, l.title
ORDER BY cnt_photos desc
或者,您可以使用子查询来计算匹配的照片。这是使用横向连接执行此操作的一种方法:
select l.*, lp.*
from locations l
cross apply (select count(*) cnt_photos from location_photos lp where lp.locationid = l.id) lp
ORDER BY lp.cnt_photos desc
I want to select rows from [locations] and order the results by the number of rows are associated with each location in [location_photos]
您可以在 ORDER BY
子句中使用相关子查询:
select l.*
from locations l
order by (select count(*)
from location_photos lp
where lp.location_id = l.id
) desc;
如果您想要查询中的计数以及排序标准,只需将子查询移动到 select
:
select l.*,
(select count(*)
from location_photos lp
where lp.location_id = l.id
) as num_photos
from locations l
order by num_photos desc;