显示sql查询中多次计数的结果

时间:2017-10-09 19:14:14

标签: sql sql-server tsql pivot

有两个表:

persons

P_id     Name     BirthDate
1            N1       2016-08-02
2            N2       2015-05-02
3            N3       2013-06-01
4            N4       2014-01-09

访问过的表:( p_id是表人的外键)

Id.     Visitor_id.     P_id.     Visit_date
1          10              1         2017-03-05
2          11              2         2017-01-01
3          10              2         2017-02-03
4          12              3         2016-05-07
5          11              4         2016-04-09
6          10              1         2017-04-09

我们将按visit_date visitor_id的日期计算他们的老人在1岁之间,1至2岁之间,2至3岁之间的被访问人数。

结果如:

Visitor_id    Under_one     Bet_one_two    Bet_two_three 
10                  2               1               0
11                  0               1               1
12                  0               0               1

有谁能帮我在sql server中编写查询以获取结果?

在上面的结果中,0,1,2意味着我们减去两个日期(visited_date - birthdate),例如:2013/03/05 - 2011/06/07的结果是1到2之间

3 个答案:

答案 0 :(得分:0)

您可以尝试下面的透视查询

select 
    visitor_id,
    Under_one=ISNULL([0],0),
    Bet_one_two=ISNULL([1],0),
    Bet_two_three=ISNULL([2],0)
from 
(
select visitor_id, datediff(m,BirthDate,visit_date)/12 age_in_years,count(1) count from persons p join 
visited v on p.p_id=v.p_id
group by visitor_id,datediff(m,BirthDate,visit_date)/12
) src
pivot
(
    max(count) for age_in_years in ([0],[1],[2])
 )p

see live demo

答案 1 :(得分:0)

如下:

CREATE TABLE persons
    (p_id int, name varchar(5), birthday date);

INSERT INTO persons
    (p_id, name, birthday)
VALUES
    (1, 'N1', '2016-08-02'),
    (2, 'N2', '2015-05-02'),
    (3, 'N3', '2013-06-01'),
    (4, 'N4', '2014-01-09');

 CREATE TABLE visited
    (id int, visitor_id int,p_id int, visit_date date)
;
INSERT INTO visited(id, visitor_id,p_id, visit_date)
VALUES
(1,10,1,'2017-03-05'),
(2,11,2,'2017-01-01'),
(3,10,2,'2017-02-03'),
(4,12,3,'2016-05-07'),
(5,11,4,'2016-04-09'),
(6,10,1,'2017-04-09');



WITH visitAge(visitor_ID, VisitAge) AS
(SELECT 
    v.visitor_ID, DateDiff(Year, birthday,visit_date) as VisitAge
FROM visited v
     INNER JOIN persons p on v.p_ID = p.p_ID
)
SELECT
    visitor_ID, 
    SUM(CASE WHEN  VisitAge < 1 THEN 1 ELSE 0  END ) AS under_one,
    SUM(CASE WHEN  VisitAge >= 1 AND  VisitAge < 2 THEN 1 ELSE 0 END  ) AS Bet_one_two,
    SUM(CASE WHEN  VisitAge >= 2 AND  VisitAge < 3 THEN 1 ELSE 0 END  )  AS Bet_two_three
FROM
  visitAge
GROUP BY visitor_ID;  

不是持久的解决方案...但是对于我在问题中看到的......这对你来说是一个开始.... SQL Fiddle link

答案 2 :(得分:0)

/*

DROP TABLE Visited
DROP TABLE Persons
DROP TABLE #Data
DROP TABLE #Results

*/

CREATE TABLE Persons
(
[P_id.] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Name] NVARCHAR(2),
BirthDate DATETIME
)
INSERT INTO PERSONS ([Name],BirthDate) VALUES ('N1','2016-08-02')
INSERT INTO PERSONS ([Name],BirthDate) VALUES ('N2','2015-05-02')
INSERT INTO PERSONS ([Name],BirthDate) VALUES ('N3','2013-06-01')
INSERT INTO PERSONS ([Name],BirthDate) VALUES ('N4','2014-01-09')
GO

CREATE TABLE Visited
(
[ID.] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Visitor_id.] INT,
[P_id.] INT REFERENCES Persons,
Visit_date DATETIME
)
GO
INSERT INTO Visited ([Visitor_id.],[P_id.],Visit_date) VALUES (10,1,'2017-03-05')
INSERT INTO Visited ([Visitor_id.],[P_id.],Visit_date) VALUES (11,2,'2017-01-01')
INSERT INTO Visited ([Visitor_id.],[P_id.],Visit_date) VALUES (10,2,'2017-02-03')
INSERT INTO Visited ([Visitor_id.],[P_id.],Visit_date) VALUES (12,3,'2016-05-07')
INSERT INTO Visited ([Visitor_id.],[P_id.],Visit_date) VALUES (11,4,'2016-04-09')
INSERT INTO Visited ([Visitor_id.],[P_id.],Visit_date) VALUES (10,1,'2017-04-09')
GO

SELECT [Visitor_id.],
CASE WHEN DATEPART(YY,v.visit_date-p.birthdate) = 1900 THEN 'Under_one'
     WHEN DATEPART(YY,v.visit_date-p.birthdate) = 1901 THEN 'Bet_one_two'
     WHEN DATEPART(YY,v.visit_date-p.birthdate) = 1902 THEN 'Bet_two_three'
END AS Age,
COUNT([Visitor_id.]) AS Number
INTO #Data
FROM Persons p INNER JOIN Visited v on p.[P_id.]=v.[P_id.]
GROUP BY [Visitor_id.],DATEPART(YY,v.visit_date-p.birthdate)
GO

CREATE TABLE #Results
(
Visitor_ID INT,
Under_one INT,
Bet_one_two INT,
Bet_two_three INT
)
GO

DECLARE @Visitor_id INT = (SELECT MIN([Visitor_id.]) FROM #Data)
WHILE @Visitor_id <= (SELECT MAX([Visitor_id.]) FROM #Data)
BEGIN
INSERT INTO #Results VALUES
(
(SELECT @Visitor_id)
,
(SELECT Number FROM #Data WHERE [Visitor_id.]=@Visitor_id AND Age = 'Under_one')
,
(SELECT Number FROM #Data WHERE [Visitor_id.]=@Visitor_id AND Age = 'Bet_one_two')
,
(SELECT Number FROM #Data WHERE [Visitor_id.]=@Visitor_id AND Age = 'Bet_two_three')
)
SET @Visitor_id = @Visitor_id + 1
END

UPDATE #Results SET Under_one = 0 WHERE Under_one IS NULL
GO
UPDATE #Results SET Bet_one_two = 0 WHERE Bet_one_two IS NULL
GO
UPDATE #Results SET Bet_two_three = 0 WHERE Bet_two_three IS NULL
GO

SELECT * FROM #Results