Shi*_*r K 4 sql-server relational-division
如果有人可以帮助我进行下面的查询,那就太好了!这个查询很有挑战性,我尝试自己做,但无法显示正确的结果......
我使用类似于“Facebook”的系统的数据库。
查询应显示去年为每个帖子发表评论的用户的电子邮件和姓名,这些帖子由他们的每个朋友发布。
意思是,我只想显示对所有朋友的所有帖子发表评论的人。
这是我的试验,但我收到了部分结果。我无法理解我做错了什么。
select distinct U.Mail, U.FirstName + ' ' + U.LastName as FullName
from Users U
inner join FriendsList FL on U.Mail = FL.Mail1
inner join Post P on FL.Mail2 = P.UserMail
left outer join Comment C on P.ID = C.IDPost and P.UserMail <> C.Mail
where datediff(year, P.DatePosted, getdate()) <= 1
group by U.Mail, U.FirstName, U.LastName
having count(distinct P.ID) = count(distinct C.IDPost)
Run Code Online (Sandbox Code Playgroud)
BAK文件链接(包括测试数据):https : //file.io/SagvM3cx
例子:
让我们假设 I & Adam & Ben 是朋友。
?? 第一种情况:
然后,我的名字应该不会在查询中显示。
然后,我的名字应该显示在查询中。
?? 第二种情况:
然后,我的名字应该不会在查询中显示。
然后,我的名字应该显示在查询中。
?? 第三种情况:
然后,我的名字应该显示在查询中。
编辑:我添加了 8 个查询 - 4create table
和 4 insert
。根据这个例子,上面的查询应该只显示Kelly
create table Users
(
Mail nvarchar (20) primary key check(Mail like '_%@_%._%' and (Mail like '%[0-9]%' Or Mail like '%[a-z]%'Or Mail like '%[A-Z]%')),
Password nvarchar (8) check (Password like '%[0-9]%' and Password like '%[az]%' and len(password) <= 8) not null,
FirstName nvarchar (20) not null,
LastName nvarchar (20) not null,
BirthDate date check (datediff(year,BirthDate,getdate())>=18) not null,
JoinDate date check (JoinDate<=getdate()) not null,
Gender nchar(1) check(Gender = 'F' or Gender = 'M' or Gender = 'O'),
NickName nvarchar(20),
Photo nvarchar(20),
Phone bigint check (Phone like '%[0-9]%' and len(Phone) <= 10) not null
)
INSERT INTO Users
VALUES
('Kelly@gmail.com','k1000000','Kelly','Ka','1992-05-15','2016-09-04','F','Kelly','Kelly.jpg','546296100'),
('Lilly@gmail.com','l1101111','Lilly','La','1999-04-03','2012-04-04','F','Lilly','Lilly.jpg','542448300'),
('Moshe@gmail.com','m120121','Moshe','Ma','1995-06-03','2011-04-02','M','Moshe','MosheMa.jpg','542840111'),
('Nelly@gmail.com','n130131','Nelly','Na','1994-03-07','2020-04-13','F','Nelly','NellyNa.jpg','541234567');
('Owen@gmail.com','o140141','Owen','Oa','1992-02-02','2020-05-13','M','Owen','OwenOa.jpg','541234567');
create table FriendsList
(
Mail1 nvarchar (20) references Users(Mail) not null,
Mail2 nvarchar (20) references Users(Mail) not null,
DateAdding date check (DateAdding<=getDate()) not null,
primary key (Mail1,Mail2)
)
INSERT INTO FriendsList
VALUES
('Kelly@gmail.com','Nelly@gmail.com','2018-04-18'),
('Lilly@gmail.com','Moshe@gmail.com','2020-04-22'),
('Moshe@gmail.com','Lilly@gmail.com','2020-04-22'),
('Moshe@gmail.com','Nelly@gmail.com','2020-04-22'),
('Nelly@gmail.com','Kelly@gmail.com','2018-04-18');
('Nelly@gmail.com','Moshe@gmail.com','2020-04-22'),
create table Post
(
ID int identity(1,1) primary key,
Photo nvarchar(20),
Text nvarchar(200),
Location nvarchar(50),
Video int,
DatePosted date check (datediff(month,DatePosted,getdate())<=3) not null,
UserMail nvarchar (20) references Users(Mail) on delete cascade on update
cascade not null
)
INSERT INTO Post
VALUES
('','my name is nellu','','','2020-04-18','Nelly@gmail.com'),
('','hii','','','2020-05-19','Lilly@gmail.com');
create table Comment
(
IDPost int references Post(ID) on delete cascade on update cascade not null,
SerialNumComment int check(SerialNumComment > 0) not null,
DateAndTimeComment Datetime check (DateAndTimeComment<=getDate()) not null,
Text nvarchar(200) not null,
Mail nvarchar (20) references Users(Mail) not null,
primary key (IDPost,SerialNumComment)
)
INSERT INTO Comment
VALUES
('1','1','2020-04-18','blabla','Kelly@gmail.com'),
('2','1','2020-05-05','bhfk','Moshe@gmail.com');
Run Code Online (Sandbox Code Playgroud)
您原始查询中的问题是
left outer join Comment C on P.ID = C.IDPost and P.UserMail <> C.Mail
Run Code Online (Sandbox Code Playgroud)
应该
left outer join Comment C on P.ID = C.IDPost and U.Mail = C.Mail
Run Code Online (Sandbox Code Playgroud)
您正在尝试获取原始用户发布的评论
就我个人而言,我发现双重NOT EXISTS
方法更容易遵循(尽管如何对待没有符合条件的帖子发表评论的用户的语义有所不同)。
您正在寻找其中一位朋友最近没有发表评论的用户。
这实现了该逻辑
SELECT U.Mail,
U.FirstName + ' ' + U.LastName AS FullName
FROM Users U
WHERE NOT EXISTS (
--A post by one of their friends in the last year
SELECT *
FROM FriendsList FL
INNER JOIN Post P
ON FL.Mail2 = P.UserMail
WHERE U.Mail = FL.Mail1
AND P.DatePosted >= DATEADD(YEAR, -1, GETDATE())
AND NOT EXISTS (
--A comment by the user on that post
SELECT *
FROM Comment C
WHERE P.ID = C.IDPost
AND U.Mail = C.Mail))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
52 次 |
最近记录: |