我有我的数据库设置,允许用户"喜欢"或者"不喜欢"一个帖子。如果它被喜欢,则列isliked = true,否则为false(如果没有则为null。)
问题是,我正在尝试创建一个显示所有帖子的视图,并且还会显示一个列有多少'喜欢'并且不喜欢'每个帖子都有。这是我的SQL;我不确定从哪里开始。自从我使用SQL之后已经有一段时间了,到目前为止我所尝试的一切都没有给我我想要的东西。
也许我的数据库没有正确设置。这是SQL:
Select trippin.AccountData.username, trippin.PostData.posttext,
trippin.CategoryData.categoryname, Count(trippin.LikesDislikesData.liked)
as TimesLiked from trippin.PostData
inner join trippin.AccountData on trippin.PostData.accountid = trippin.AccountData.id
inner join trippin.CategoryData on trippin.CategoryData.id = trippin.PostData.categoryid
full outer join trippin.LikesDislikesData on trippin.LikesDislikesData.postid =
trippin.PostData.id
full outer join trippin.LikesDislikesData likes2 on trippin.LikesDislikesData.accountid =
trippin.AccountData.id
Group By (trippin.AccountData.username), (trippin.PostData.posttext), (trippin.categorydata.categoryname);
这是我的表设置(我只包括相关列):
LikesDislikesData
isliked(bit) || accountid(string) || postid(string
PostData
id(string) || posttext || accountid(string)
AccountData
id(string) || username(string)
CategoryData
categoryname(string)
答案 0 :(得分:1)
而不是选择Count(trippin.LikesDislikesData.liked)
,您可以放入一个选择语句:
Select AccountData.username, PostData.posttext, CategoryData.categoryname,
(select Count(*)
from LikesDislikesData as likes2
where likes2.postid = postdata.id
and likes2.liked = 'like' ) as TimesLiked
from PostData
inner join AccountData on PostData.accountid = AccountData.id
inner join CategoryData on CategoryData.id = PostData.categoryid
答案 1 :(得分:1)
问题1:全外连接与左外连接。完全外连接很少是你想要的,它意味着你想要在“左”上指定的所有数据和在“右”上指定的所有数据,它们是匹配的和不匹配的。你想要的是“左”的所有PostData和“右”的任何匹配的喜欢数据。如果右侧的某些行与左侧的内容不匹配,那么您不关心。几乎总是从左到右工作并加入相关的结果。
问题2:表别名。除了表名称(例如Likes2)之外,查询中该表的每个实例都需要使用该别名。在声明别名Likes2之后,您的连接条件会直接返回trippin.LikesDislikesData,这是表的第一个实例。鉴于加入另一个字段的第二个我怀疑postid和accountid在同一行上匹配,因此它应该是AND在一起,而不是一个单独的表实例。编辑阅读你的架构更近,似乎根本不需要。
问题3:解决你的问题使用CASE语句将问题分开。 Count将添加为每个CASE返回的非NULL值的数量。如果likes.liked = 1,则返回1否则返回NULL。如果列包含0或NULL,则返回NULL。
SELECT trippin.PostData.Id, trippin.AccountData.username, trippin.PostData.posttext,
trippin.CategoryData.categoryname,
SUM(CASE WHEN likes.liked = 1 THEN 1 ELSE 0 END) as TimesLiked,
SUM(CASE WHEN likes.liked = 0 THEN 1 ELSE 0 END) as TimesDisLiked
FROM trippin.PostData
INNER JOIN trippin.AccountData ON trippin.PostData.accountid = trippin.AccountData.id
INNER JOIN trippin.CategoryData ON trippin.CategoryData.id = trippin.PostData.categoryid
LEFT OUTER JOIN trippin.LikesDislikesData likes ON likes.postid = trippin.PostData.id
-- remove AND likes.accountid = trippin.AccountData.id
GROUP BY trippin.PostData.Id, (trippin.AccountData.username), (trippin.PostData.posttext), (trippin.categorydata.categoryname);
然后在用户界面中“隐藏”PostId列。
答案 2 :(得分:0)
USE AdventureWorksDW2008R2
GO
SET NOCOUNT ON
GO
/*
Default
*/
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
GO
BEGIN TRAN
IF OBJECT_ID('tempdb.dbo.#LikesDislikesData') IS NOT NULL
BEGIN
DROP TABLE #LikesDislikesData
END
CREATE TABLE #LikesDislikesData(
isLiked bit
,accountid VARCHAR(50)
,postid VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#PostData') IS NOT NULL
BEGIN
DROP TABLE #PostData
END
CREATE TABLE #PostData(
postid INT IDENTITY(1,1) NOT NULL
,accountid VARCHAR(50)
,posttext VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#AccountData') IS NOT NULL
BEGIN
DROP TABLE #AccountData
END
CREATE TABLE #AccountData(
accountid INT
,username VARCHAR(50)
);
IF OBJECT_ID('tempdb.dbo.#CategoryData') IS NOT NULL
BEGIN
DROP TABLE #CategoryData
END
CREATE TABLE #CategoryData(
categoryname VARCHAR(50)
);
INSERT INTO #AccountData VALUES ('1', 'user1')
INSERT INTO #PostData VALUES('1','this is a post')
INSERT INTO #LikesDislikesData (isLiked ,accountid, postid)
SELECT '1', P.accountid, P.postid
FROM #PostData P
WHERE P.posttext = 'this is a post'
SELECT *
FROM #PostData
SELECT *
FROM #LikesDislikesData
SELECT *
FROM #AccountData
SELECT COUNT(L.isLiked) 'Likes'
,P.posttext
,A.username
FROM #PostData P
JOIN #LikesDislikesData L
ON P.accountid = L.accountid
AND L.IsLiked = 1
JOIN #AccountData A
ON P.accountid = A.accountid
GROUP BY P.posttext, A.username
SELECT X.likes, Y.dislikes
FROM (
(SELECT COUNT(isliked)as 'likes', accountid
FROM #LikesDislikesData
WHERE isLiked = 1
GROUP BY accountid
) X
JOIN
(SELECT COUNT(isliked)as 'dislikes', accountid
FROM #LikesDislikesData
WHERE isLiked = 0
GROUP BY accountid) Y
ON x.accountid = y.accountid)
IF (XACT_STATE() = 1 AND ERROR_STATE() = 0)
BEGIN
COMMIT TRAN
END
ELSE IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK TRAN
END
答案 3 :(得分:-1)
您如何看待解决方案?我们创建一个新表SummaryReport(PostID,AccountID,NumberOfLikedTime,NumberOfDislikedTimes)。
用户点击LIKE或DISLIKE按钮我们更新表格。之后,您可以根据需要进行查询。另一个优点是,该表可以用于报告目的。