向SQL发送布尔值并将表更新为1或-1,以及如何“更新”初始值的空行
我有一个带有likes列的Songs表,其中包含发送的likes用户数。每个用户通过一个C应用程序发送一个布尔值1或0,该应用程序将添加到likes列 关于我的程序:向SQL发送布尔值并将表更新为1或-1,以及如何“更新”初始值的空行,sql,sql-server,sql-server-2008,if-statement,boolean,Sql,Sql Server,Sql Server 2008,If Statement,Boolean,我有一个带有likes列的Songs表,其中包含发送的likes用户数。每个用户通过一个C应用程序发送一个布尔值1或0,该应用程序将添加到likes列 关于我的程序: CREATE PROCEDURE Songs_Likes @User_ID INT, @SongID INT, @Song_like BIT AS BEGIN --- part 1 of the function IF (@Song_like = 1) BEGIN U
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
我想知道是否有更有效、更简短的方法来编写函数的第1部分?
我第一次必须手动插入“0”而不是空值,函数才能工作。它不起作用,因为Likes列的初始值为NULL。当行中有空值时,是否有方法第一次影响该行
对于带有[Users\u Likes\u Songs]表的函数的第2部分,我想更新用户是否发送like 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
您可以在过程中尝试此查询
UPDATE [songs]
SET [likes] = Isnull ([likes], 0) + ( CASE WHEN @Song_like THEN 1 ELSE -1 END)
WHERE [song_id] = @SongID
您可以在过程中尝试此查询
UPDATE [songs]
SET [likes] = Isnull ([likes], 0) + ( CASE WHEN @Song_like THEN 1 ELSE -1 END)
WHERE [song_id] = @SongID
对于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)
对于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)
我认为更好的方法是改变你的设计来计算喜好,并有一个表来存储每个用户的喜好。简单地说,类似于:
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
我认为更好的方法是改变你的设计来计算喜好,并有一个表来存储每个用户的喜好。简单地说,类似于:
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
为什么需要在歌曲表中存储喜欢的数量?您总是可以从Users_Likes_Songs表中计算它。对于您的注释B,为什么不将Likes的默认值设置为0,而不是NULL?然而,理想情况下,我会实际计算喜欢的数字作为计算值。存储在表中很容易以错误的值结束;特别是在比赛条件方面。@HoneyBadger,这是个好主意,但对于演示项目,我必须插入没有实际用户的“假”喜欢。@sup.DR我想说,没有用户,即使是演示,你也不能有喜欢。如果你需要演示,创建假用户,让他们喜欢和不喜欢歌曲。为什么你需要在歌曲表中存储喜欢的数量?您总是可以从Users_Likes_Songs表中计算它。对于您的注释B,为什么不将Likes的默认值设置为0,而不是NULL?然而,理想情况下,我会实际计算喜欢的数字作为计算值。存储在表中很容易以错误的值结束;特别是在比赛条件方面。@HoneyBadger,这是个好主意,但对于演示项目,我必须插入没有实际用户的“假”喜欢。@sup.DR我想说,没有用户,即使是演示,你也不能有喜欢。如果您需要演示,请创建假用户,让他们喜欢或不喜欢歌曲。您的代码中有一个勘误表:ESLE->ELSE。另外,COALESCE比ISNULL更为推荐,因为ANSII标准在您的代码中有一个勘误表:ESLE->ELSE。另外,COALESCE比ISNULL更受推荐,因为ANSII标准更新了我的问题的第二部分,你能看一下吗?我想知道你的我是否正确理解你的答案。谢谢你,只需要用更少的as编辑你的答案-从[Users\u Likes\u Songs]中选择1,其中[UserID]=@User\u ID和[SongID]=@SongID啊,是的。。。有一些令人困惑的地方,还有一个地方不见了。在我的回复中已修复,以供将来参考。谢谢分享!!!我更新了问题的第二部分,你能看一下吗?我想知道你的我是否正确理解你的答案。谢谢你,只需要用更少的as编辑你的答案-从[Users\u Likes\u Songs]中选择1,其中[UserID]=@User\u ID和[SongID]=@SongID啊,是的。。。有一些令人困惑的地方,还有一个地方不见了。在我的回复中已修复,以供将来参考。谢谢分享!!!我会为引用songID的SongsLikes表添加一个约束FK。这只是最基本的。我不会为OP做所有的工作:我会为SongsLikes表添加一个约束FK来引用songID。它需要几个索引和约束,@Sami。这只是最基本的。我没有为OP做所有的工作: