有两个表:
表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之间
答案 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