针对一个CTE进行多重选择

19 t-sql sql-server

我有一个CTE查询过滤表Student

  Student

   (
    StudentId PK,
    FirstName ,
    LastName,
    GenderId,
    ExperienceId,
    NationalityId,
    CityId
  )
Run Code Online (Sandbox Code Playgroud)

基于很多过滤器(多个城市,性别,多种体验(1,2,3),多个国家),我使用动态sql创建CTE并使用用户定义的表(CityTable, NationalityTable,...)加入学生表

之后,我必须通过每个过滤器检索学生的数量

CityId City Count

NationalityId Nationality Count
Run Code Online (Sandbox Code Playgroud)

其他过滤器也一样.

我能做点什么吗

  ;With CTE(
         Select
         FROM Student
         Inner JOIN ...
         INNER JOIN ....)
  SELECT CityId,City,Count(studentId)
  FROm CTE
  GROUP BY CityId,City

  SELECT GenderId,Gender,Count
  FROM CTE
  GROUP BY  GenderId,Gender
Run Code Online (Sandbox Code Playgroud)

我想要像LinkedIn正在做什么搜索(人们搜索,求职)

http://www.linkedin.com/search/fpsearch?type=people&keywords=sales+manager&pplSearchOrigin=GLHD&pageKey=member-home

这是如此之快,做同样的事情.

Sha*_*esh 16

您不能使用多个选择,但您可以使用多个这样的CTE.

WITH CTEA
AS
(
SELECT 'Coulmn1' A,'Coulmn2' B
),
CETB
AS
(
SELECT 'CoulmnX' X,'CoulmnY' Y
)

SELECT * FROM CTEA, CETB
Run Code Online (Sandbox Code Playgroud)

为了获得计数使用RowNumber和CTE,有些人会这样想.

ROW_NUMBER() OVER ( ORDER BY COLUMN NAME )AS RowNumber,
Count(1) OVER() AS TotalRecordsFound
Run Code Online (Sandbox Code Playgroud)

如果您需要更多相关信息,请与我们联系.

样品供您参考.

With CTE AS (
         Select StudentId, S.CityId, S.GenderId
         FROM Student S
         Inner JOIN CITY C
         ON S.CityId = C.CityId
         INNER JOIN GENDER G
         ON S.GenderId = G.GenderId)
,
GENDER
AS
(
  SELECT GenderId
  FROM CTE
  GROUP BY  GenderId
  )


SELECT * FROM GENDER, CTE
Run Code Online (Sandbox Code Playgroud)


Eli*_*nti 9

从单个CTE获取多个结果集是不可能的.但是,您可以使用表变量来缓存某些信息,并在以后使用它,而不是多次发出相同的复杂查询:

declare @relevantStudent table (StudentID int);

insert into @relevantStudent
select s.StudentID from Students s
join ...
where ...

-- now issue the multiple queries

select s.GenderID, count(*)
from student s
join @relevantStudent r on r.StudentID = s.StudentID
group by s.GenderID

select s.CityID, count(*)
from student s
join @relevantStudent r on r.StudentID = s.StudentID
group by s.CityID
Run Code Online (Sandbox Code Playgroud)

诀窍是只在表变量中存储最少的必需信息.
与任何查询一样,这是否会实际上提高性能而不是独立发出查询取决于许多事情(表变量数据集有多大,用于填充它的查询有多复杂以及后续连接/子选择对复杂的有多复杂)表变量等).


Dou*_*g S 6

执行UNION ALL多个操作SELECT并将结果连接到一个表中.

  ;WITH CTE AS(
         SELECT
         FROM Student
         INNER JOIN ...
         INNER JOIN ....)
  SELECT CityId,City,Count(studentId),NULL,NULL
         FROM CTE
         GROUP BY CityId,City
  UNION ALL
  SELECT NULL,NULL,NULL,GenderId,Gender,Count
         FROM CTE
         GROUP BY GenderId,Gender
Run Code Online (Sandbox Code Playgroud)

注意:NULL上面的值只允许两个结果具有匹配的列,因此可以连接结果.


ric*_*ent 5

我知道这是一个非常古老的问题,但这是我刚刚使用的解决方案。我有一个存储过程,它返回搜索结果的 PAGE,我还需要它返回与查询参数匹配的总数。

WITH results AS (...complicated foo here...)

SELECT results.*,
    CASE 
      WHEN @page=0 THEN (SELECT COUNT(*) FROM results)
      ELSE -1
    END AS totalCount 
FROM results
ORDER BY bar
OFFSET @page * @pageSize ROWS FETCH NEXT @pageSize ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)

使用这种方法,在第一个结果页面上有一个小的“命中”来获取计数,对于剩余的页面,我传回“-1”以避免命中(我假设结果数量在用户会话)。即使为第一页结果的每一行返回 totalCount,它也只计算一次。

我的 CTE 正在根据存储过程参数进行大量过滤,因此我不能将其移动到视图并查询两次。这种方法可以避免为了获得计数而必须复制 CTE 的逻辑。