【问题标题】:Sending SQL a boolean and update a table as 1 or -1 and how to "update" an empty row for the initial values向 SQL 发送布尔值并将表更新为 1 或 -1 以及如何“更新”初始值的空行
【发布时间】:2019-01-02 12:45:10
【问题描述】:

我有一个Songs 表,其中有一个likes 列,其中包含用户发送的点赞数。每个用户通过 C# 应用程序发送一个布尔值(1 或 0),该应用程序添加到 likes 列。

关于我的程序:

  1. 我想知道是否有更有效和简短的方法来编写函数的第 1 部分?
    我必须第一次手动插入 '0' 而不是 NULL 才能使该功能正常工作。它不起作用,因为Likes 列的初始值为NULL。当行中有NULL时,有没有办法第一次影响行?

  2. 对于[Users_Likes_Songs] 表的函数的第 2 部分,我想更新用户是否发送了一个赞 (true = 1) 或删除它 (false = 0)。

    当用户的“like”必须被赋值为“1”时,我如何第一次更新这个表,而它的行完全是空的?

如果你能帮助我,我非常感谢你。

程序:

CREATE PROCEDURE Songs_Likes
    @User_ID INT,
    @SongID INT,
    @Song_like BIT
AS
BEGIN
    --- part 1 of the function
    IF (@Song_like = 1)
    BEGIN
        UPDATE [Songs] 
        SET [Likes] = [Likes] + @Song_like
        WHERE [Song_ID] = @SongID
    END

    IF (@Song_like = 0)
    BEGIN
        UPDATE [Songs] 
        SET [Likes] = [Likes] - 1
        WHERE [Song_ID] = @SongID
    END

    --- part 2 of the function with the second table
    UPDATE [Users_Likes_Songs]
    SET [LikeSong] = @Song_like 
    WHERE ([UserID] = @User_ID) AND ([SongID] = @SongID)
END

【问题讨论】:

  • 为什么需要在Songs表中存储点赞数?您总是可以从Users_Likes_Songs 表中计算出来。
  • 关于您的评论 B,为什么不将 LikesDEFAULT 值设置为 0,而不是 NULL?然而,理想情况下,我实际上会将喜欢的数量计算为计算值。存储在表中很容易以不正确的值结束;尤其是在比赛条件等方面。
  • @HoneyBadger,这是个好主意,但对于演示项目,我必须在没有实际用户的情况下插入“假”喜欢。
  • @sup.DR 我想说没有用户你就不可能有喜欢,即使是演示。如果您需要演示,创建假用户,让他们喜欢和不喜欢歌曲。

标签: sql sql-server sql-server-2008 if-statement boolean


【解决方案1】:

我认为更好的方法是改变你的设计来计算喜欢,并有一个表来存储每个用户的喜欢。简单来说,类似:

USE Sandbox;
GO

CREATE SCHEMA music;
GO

CREATE TABLE music.song (SongID int IDENTITY(1,1),
                         Artist nvarchar(50) NOT NULL,
                         Title nvarchar(50) NOT NULL,
                         ReleaseDate date);

CREATE TABLE music.[User] (UserID int IDENTITY(1,1),
                           [Login] nvarchar(128));

CREATE TABLE music.SongLike (LikeID bigint IDENTITY(1,1),
                             SongID int,
                             UserID int,
                             Liked bit);

CREATE UNIQUE NONCLUSTERED INDEX UserLike ON music.SongLike(SongID, UserID); --Stops multiple likes
GO

--To add a LIKE you can then have a SP like:

CREATE PROC music.AddLike @SongID int, @UserID int, @Liked bit AS
BEGIN

    IF EXISTS (SELECT 1 FROM music.SongLike WHERE UserID = @UserID AND SongID = @SongID) BEGIN
        UPDATE music.SongLike
        SET Liked = @Liked
        WHERE UserID = @UserID
          AND SongID = @SongID
    END ELSE BEGIN
        INSERT INTO music.SongLike (SongID,
                                    UserID,
                                    Liked)
        VALUES (@SongID, @UserID, @Liked);
    END
END
GO

--And, if you want the number of likes:

CREATE VIEW music.SongLikes AS

    SELECT S.Artist,
           S.Title,
           S.ReleaseDate,
           COUNT(CASE SL.Liked WHEN 1 THEN 1 END) AS Likes
    FROM music.Song S
         JOIN music.SongLike SL ON S.SongID = SL.SongID
    GROUP BY S.Artist,
             S.Title,
             S.ReleaseDate;
GO

【讨论】:

  • 我会为 SongsLikes 表添加一个约束 (FK) 引用歌曲 ID。
  • 它需要几个索引和约束,@Sami。这只是最基本的。我没有为 OP 做所有的工作 :)
【解决方案2】:

对于 1),这更清晰、更短且更高效。

UPDATE [Songs] 
    SET [Likes] = COALESCE([Likes], 0) + CASE WHEN @Song_like = 1 THEN 1
                                WHEN @Song_like = 0 THEN -1
                                ELSE 0 END
    WHERE [Song_ID] = @SongID;

对于第二部分,您可以这样做:

IF NOT EXISTS (SELECT 1 
    FROM [Users_Likes_Songs] 
    WHERE [UserID] = @User_ID 
    AND [SongID] = @SongID) 

  INSERT INTO [Users_Likes_Songs] (User_ID, SongID, [LikeSong]) 
    VALUES (@User_ID, @SongID, @Song_like)
ELSE
  UPDATE [Users_Likes_Songs]
    SET [LikeSong] = @Song_like WHERE ([UserID] = @User_ID) AND ([SongID] = @SongID)

【讨论】:

  • 我更新了我的问题的第二部分,你能看一下吗?我想知道您的回答是否正确。
  • 谢谢,只需用 less ')' '(' as - (SELECT 1 FROM [Users_Likes_Songs] WHERE [UserID] = @User_ID AND [SongID] = @SongID) 编辑您的答案
  • 啊,是的...有一些令人困惑的 () 和缺少的 )。在我的回复中修复以供将来参考。谢谢分享!!!
【解决方案3】:

你可以在你的过程中尝试这个查询

UPDATE [songs] 
SET    [likes] = Isnull ([likes], 0) + ( CASE WHEN @Song_like THEN 1 ELSE -1 END) 
WHERE  [song_id] = @SongID 

【讨论】:

  • 您的代码中有一个错误:“ESLE”-->“ELSE”。此外,与 ANSII 标准一样,COALESCE 比 ISNULL 更推荐
猜你喜欢
  • 2018-05-22
  • 2013-05-10
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-08
  • 1970-01-01
相关资源
最近更新 更多