Rhonda
Rhonda

Reputation: 1721

Simplify MS SQL Statements

I read a great post on JOINS, What is the difference between "INNER JOIN" and "OUTER JOIN"? but I don't think it helps my issue.

I would like to combine two select statements into a single select statement AND, make it efficient for any databases to query.

Here is what I have

SELECT
(SELECT COUNT(*) 
                        FROM dbo.sem_computer, [dbo].[V_SEM_COMPUTER], dbo.IDENTITY_MAP, dbo.SEM_CLIENT,dbo.SEM_AGENT,dbo.PATTERN
                        WHERE [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
                        AND dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID
                        AND dbo.SEM_CLIENT.COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
                        AND SEM_COMPUTER.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID
                        AND dbo.PATTERN.PATTERN_IDX = dbo.SEM_AGENT.PATTERN_IDX
                        AND Name like '%Staten Island%'
                        AND dbo.SEM_AGENT.AGENT_VERSION LIKE '11.%'
                        AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE 'Windows%') AS 'Windows-SEP-11',
(SELECT COUNT(*) 
                        FROM dbo.sem_computer, [dbo].[V_SEM_COMPUTER], dbo.IDENTITY_MAP, dbo.SEM_CLIENT,dbo.SEM_AGENT,dbo.PATTERN
                        WHERE [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
                        AND dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID
                        AND dbo.SEM_CLIENT.COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
                        AND SEM_COMPUTER.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID
                        AND dbo.PATTERN.PATTERN_IDX = dbo.SEM_AGENT.PATTERN_IDX
                        AND Name like '%Staten Island%'
                        AND dbo.SEM_AGENT.AGENT_VERSION LIKE '12.%'
                        AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE 'Windows%') AS 'Windows-SEP-12',
(SELECT COUNT(*) 
                        FROM dbo.sem_computer, [dbo].[V_SEM_COMPUTER], dbo.IDENTITY_MAP, dbo.SEM_CLIENT,dbo.SEM_AGENT,dbo.PATTERN
                        WHERE [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
                        AND dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID
                        AND dbo.SEM_CLIENT.COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
                        AND SEM_COMPUTER.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID
                        AND dbo.PATTERN.PATTERN_IDX = dbo.SEM_AGENT.PATTERN_IDX
                        AND Name like '%Staten Island%'
                        AND dbo.SEM_AGENT.AGENT_VERSION LIKE '11.%'
                        AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE 'Mac%') AS 'Mac-SEP-11',
(SELECT COUNT(*)
                        FROM dbo.sem_computer, [dbo].[V_SEM_COMPUTER], dbo.IDENTITY_MAP, dbo.SEM_CLIENT,dbo.SEM_AGENT,dbo.PATTERN
                        WHERE [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
                        AND dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID
                        AND dbo.SEM_CLIENT.COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
                        AND SEM_COMPUTER.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID
                        AND dbo.PATTERN.PATTERN_IDX = dbo.SEM_AGENT.PATTERN_IDX
                        AND Name like '%Staten Island%'
                        AND dbo.SEM_AGENT.AGENT_VERSION LIKE '12.%'
                        AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE 'Mac%')  AS 'Mac-SEP-12'

How to shrink this SQL statement? Even if I use Inner Joins (which I'm working on), this statement is quite processor intensive (not to mention it seems really inefficient)

Upvotes: 4

Views: 557

Answers (2)

Alexei - check Codidact
Alexei - check Codidact

Reputation: 23078

Building upon the providing answer, I think a more elegant solution is to hold filtering values in a separate table (separate logic from data).

However, this will work only if the conditions are disjoint (a pair of values will hit a maximum of one condition), otherwise multiple "hits" will count for more options.

CREATE TABLE dbo.AgentAndOsFilter
(
   Id INT IDENTITY(1, 1),
   AgentVersion VARCHAR(8),
   Os VARCHAR(16)
)

This can be populated with your filtering pairs:

INSERT INTO dbo.AgentAndOsFilter (AgentVersion, Os)
VALUES ('11.%', 'Windows%'), ('12.%', 'Windows%'), ('11.%', 'Mac%'), ('12.%', 'Mac%')

The query can look like this:

SELECT F.Id, Count(1) Cnt
FROM   dbo.sem_computer
       INNER JOIN [dbo].[V_SEM_COMPUTER]
               ON [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
       INNER JOIN dbo.SEM_AGENT
               ON SEM_COMPUTER.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID
       INNER JOIN dbo.SEM_CLIENT
               ON dbo.SEM_CLIENT.COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
       INNER JOIN dbo.IDENTITY_MAP
               ON dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID
       INNER JOIN dbo.PATTERN
               ON dbo.PATTERN.PATTERN_IDX = dbo.SEM_AGENT.PATTERN_IDX
       INNER JOIN dbo.AgentAndOsFilter F 
               ON dbo.SEM_AGENT.AGENT_VERSION LIKE F.AgentVersion 
                   AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE F.Os
WHERE  Name LIKE '%Staten Island%' 
GROUP BY F.Id

Another advantage of this solution is changes in the configuration (new versions of agents, new operating systems) simply means changing some records in a table.

Upvotes: 2

Pரதீப்
Pரதீப்

Reputation: 93704

You can do this using Conditional Aggregate.

Also use proper INNER JOIN syntax to Join two tables instead of old style comma separated join. Keep the filters in Where clause

SELECT Count(CASE
               WHEN dbo.SEM_AGENT.AGENT_VERSION LIKE '11.%'
                    AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE 'Windows%' THEN 1
             END) AS 'Windows-SEP-11',
       Count(CASE
               WHEN dbo.SEM_AGENT.AGENT_VERSION LIKE '12.%'
                    AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE 'Windows%' THEN 1
             END) AS 'Windows-SEP-12',
       Count(CASE
               WHEN dbo.SEM_AGENT.AGENT_VERSION LIKE '11.%'
                    AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE 'Mac%' THEN 1
             END) AS 'Mac-SEP-11',
       Count(CASE
               WHEN dbo.SEM_AGENT.AGENT_VERSION LIKE '12.%'
                    AND dbo.SEM_COMPUTER.OPERATION_SYSTEM LIKE 'Mac%' THEN 1
             END) AS 'Mac-SEP-12'
FROM   dbo.sem_computer
       INNER JOIN [dbo].[V_SEM_COMPUTER]
               ON [dbo].[V_SEM_COMPUTER].COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
       INNER JOIN dbo.SEM_AGENT
               ON SEM_COMPUTER.COMPUTER_ID = dbo.SEM_AGENT.COMPUTER_ID
       INNER JOIN dbo.SEM_CLIENT
               ON dbo.SEM_CLIENT.COMPUTER_ID = SEM_COMPUTER.COMPUTER_ID
       INNER JOIN dbo.IDENTITY_MAP
               ON dbo.SEM_CLIENT.GROUP_ID = IDENTITY_MAP.ID
       INNER JOIN dbo.PATTERN
               ON dbo.PATTERN.PATTERN_IDX = dbo.SEM_AGENT.PATTERN_IDX
WHERE  Name LIKE '%Staten Island%' 

Upvotes: 14

Related Questions