如何使用where子句执行Count函数?

时间:2014-08-19 01:57:32

标签: sql sql-server

我有我的数据库设置,允许用户"喜欢"或者"不喜欢"一个帖子。如果它被喜欢,则列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)

4 个答案:

答案 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按钮我们更新表格。之后,您可以根据需要进行查询。另一个优点是,该表可以用于报告目的。