0

我想知道如何更好地将以下查询写入 Microsoft SQL Server。

我有三个表surveyssurvey_presetssurvey_scenes。它们具有以下列:

CREATE TABLE [dbo].[surveys](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [caption] [nvarchar](255) NOT NULL,
    [creation_time] [datetime] NOT NULL,
)
CREATE TABLE [dbo].[survey_presets](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [survey_id] [int] NOT NULL,
    [preset_id] [int] NOT NULL,
)
CREATE TABLE [dbo].[survey_scenes](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [survey_id] [int] NOT NULL,
    [scene_id] [int] NOT NULL,
)

两者都在列survey_presetssurvey_scenes有外键。surveyssurvey_id

现在我想选择所有调查,并为每个调查提供相应的预设和场景的数量。这是我想要的“伪查询”:

SELECT
    surveys.*,
    COUNT(survey_presets, where survey_presets.survey_id = surveys.id), 
    COUNT(survey_scenes, where survey_scenes.survey_id = surveys.id)
FROM surveys
ORDER BY suverys.creation_time

我可以弄乱SELECT DISTINCT, JOIN,GROUP BY等,但我是 T-SQL 的新手,我怀疑我的查询在任何意义上都是最佳的。

4

2 回答 2

2

我会在子查询中进行计数以避免笛卡尔积。因为您可能有一些匹配的行,presets并且scenes结果计数中的一些可能会成倍增加。您可能会编写简单的连接查询并通过计数来避免distinct survey_presets.id乘法distinct survey_scenes.id

SELECT
    surveys.*,
    isnull(presets_count, 0) presets_count,
    isnull(scenes_count, 0) scenes_count
FROM surveys
LEFT JOIN 
(
  SELECT survey_id,
         count(*) presets_count
    FROM survey_presets
   GROUP BY survey_id
) presets
  ON surveys.id = presets.survey_id
LEFT JOIN 
(
  SELECT survey_id,
         count(*) scenes_count
    FROM survey_scenes
   GROUP BY survey_id
) scenes
  ON surveys.id = scenes.survey_id
ORDER BY surveys.creation_time

这个怎么运作

您可以引入一种特殊的子查询,称为查询derived table的 FROM 部分。派生表定义为用括号括起来并后跟表别名的普通查询。它不能使用外部查询中的任何列,但可以公开您在 ON 部分中使用的列,以将派生表连接到查询的主体。

在这种情况下,派生表只计算按 id 分组的行数;连接将计数与调查联系起来。

于 2012-09-19T11:52:07.770 回答
0
SELECT surveys.ID, surveys.caption, surveys.creation_time,
count(survey_presets.survey_id) as survey_presets,
count(survey_scenes.survey_id)  as survey_scenes
FROM surveys
LEFT OUTER JOIN survey_presets on survey_presets.survey_id = surveys.id 
LEFT OUTER JOIN survey_scenes  on survey_scenes.survey_id  = surveys.id
GROUP BY surveys.ID, surveys.caption, surveys.creation_time
ORDER BY suverys.creation_time
于 2012-09-19T11:50:13.760 回答