2012-09-19 52 views
0

我不知道如何更好地將以下查詢寫入Microsoft SQL Server。T-SQL - 獲取加入條目數

我有三個表格: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_scenessurveys外鍵survey_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 DISTINCTJOINGROUP BY,等等,但我是新來的T-SQL,我懷疑我的查詢將在任何意義上都是最佳的。

回答

2

我會在子查詢計數,以避免笛卡爾產品。由於presets中可能有幾個匹配行,並且scenes中的一些行可能會相乘。您可以編寫簡單的連接查詢,並通過計算distinct survey_presets.iddistinct 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從您的查詢的部分。派生表被定義爲用圓括號括起來的普通查詢,後跟表別名。它不能使用來自外部查詢的任何列,但可以公開在ON部分中使用的列,以將派生表連接到查詢的主體。

在這種情況下,派生表只計算按ID分組的行;加入連接計數到調查。

+0

它的工作原理!謝謝!現在我要深入瞭解它的工作原理:) – Mikhail

+0

不客氣:-)我已經擴大了答案。 –

+0

很好的解釋。雖然我發現了一個小錯誤:如果沒有預設或場景與調查相關聯,則相應的計數等於NULL,而不是零。你能否建議如何解決這個問題? – Mikhail

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 
+0

關鍵字'LEFT'附近的語法不正確。 – Mikhail

+0

立即嘗試我從錯誤的位置 – Paparazzi

+0

消息4104,級別16,狀態1,行8 多部分標識符「suverys.creation_time」無法綁定。 - 我正在使用SQL Server 2012 – Mikhail