I wonder how better to write the following query to Microsoft SQL Server.
I have three tables: surveys, survey_presets and survey_scenes. They have the following columns:
CREATE TABLE [dbo].[surveys](
[id] [int] IDENTITY(1,1) NOT NULL,
[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,
)
Both survey_presets and survey_scenes have foreign keys on surveys for survey_id column.
Now I want to select all surveys with the count of corresponding presets and scenes for each. Here is the “pseudo-query” of what I want:
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
I can do a mess with SELECT DISTINCT, JOIN, GROUP BY, etc., but I’m new to T-SQL and I doubt my query will be optimal in any sense.
I would do the counting in subqueries to avoid cartesian products. As you might have a few matching rows in
presetsand also a few inscenesresulting count might be multiplied. You might write simple join query and avoid the multiplication by countingdistinct survey_presets.idanddistinct survey_scenes.idthough.How it works
You can introduce a special kind of subquery called
derived tableto FROM section of your query. Derived table is defined as normal query enclosed in parenthesis and followed by table alias. It cannot use any column from outer query, but can expose columns you use in ON section to join derived table to main body of the query.In this case derived table simply count rows grouped by id; joins connect the counts to surveys.