mysql - 如果满足其中一个 case 语句,如何结束 SQL case 语句?

标签 mysql sql oracle case-statement

我目前正在构建一个应用程序,该应用程序具有一个数据库,该数据库保存由四十个插槽组成的用户库存。在此数据库中,一行等于一个用户。我想要这个查询做的是搜索每个槽,当它找到一个包含零的槽时,查询应该将其更新为不同的预定数字,然后停止。然而,我遇到了我找到的解决方案的问题,查询不是在更新特定节点后停止,而是继续更新其中包含零的每个节点。更新一个节点后如何结束该查询?

代码:

SET SQL_SAFE_UPDATES = 0;
SELECT *
FROM userinfo;

UPDATE userinfo SET
InvSlot1 = CASE WHEN InvSlot1 = 0 THEN 4 ELSE InvSlot1 END,
InvSlot2 = CASE WHEN InvSlot2 = 0 THEN 4 ELSE InvSlot2 END,
InvSlot3 = CASE WHEN InvSlot3 = 0 THEN 4 ELSE InvSlot3 END,
InvSlot4 = CASE WHEN InvSlot4 = 0 THEN 4 ELSE InvSlot4 END,
InvSlot5 = CASE WHEN InvSlot5 = 0 THEN 4 ELSE InvSlot5 END,
InvSlot6 = CASE WHEN InvSlot6 = 0 THEN 4 ELSE InvSlot6 END,
InvSlot7 = CASE WHEN InvSlot7 = 0 THEN 4 ELSE InvSLot7 END,
InvSlot8 = CASE WHEN InvSlot8 = 0 THEN 4 ELSE InvSlot8 END,
InvSlot9 = CASE WHEN InvSlot9 = 0 THEN 4 ELSE InvSlot9 END,
InvSlot10 = CASE WHEN InvSlot10 = 0 THEN 4 ELSE InvSlot10 END,
InvSlot11 = CASE WHEN InvSlot11 = 0 THEN 4 ELSE InvSlot11 END,
InvSlot12 = CASE WHEN InvSlot12 = 0 THEN 4 ELSE InvSlot12 END,
InvSlot13 = CASE WHEN InvSlot13 = 0 THEN 4 ELSE InvSlot13 END,
InvSlot14 = CASE WHEN InvSlot14 = 0 THEN 4 ELSE InvSlot14 END,
InvSlot15 = CASE WHEN InvSlot15 = 0 THEN 4 ELSE InvSlot15 END,
InvSlot16 = CASE WHEN InvSlot16 = 0 THEN 4 ELSE InvSlot16 END,
InvSlot17 = CASE WHEN InvSlot17 = 0 THEN 4 ELSE InvSlot17 END,
InvSlot18 = CASE WHEN InvSlot18 = 0 THEN 4 ELSE InvSlot18 END,
InvSlot19 = CASE WHEN InvSlot19 = 0 THEN 4 ELSE InvSlot19 END,
InvSlot20 = CASE WHEN InvSlot20 = 0 THEN 4 ELSE InvSlot20 END,
InvSlot21 = CASE WHEN InvSlot21 = 0 THEN 4 ELSE InvSlot21 END,
InvSlot22 = CASE WHEN InvSlot22 = 0 THEN 4 ELSE InvSlot22 END,
InvSlot23 = CASE WHEN InvSlot23 = 0 THEN 4 ELSE InvSlot23 END,
InvSlot24 = CASE WHEN InvSlot24 = 0 THEN 4 ELSE InvSlot24 END,
InvSlot25 = CASE WHEN InvSlot25 = 0 THEN 4 ELSE InvSlot25 END,
InvSlot26 = CASE WHEN InvSlot26 = 0 THEN 4 ELSE InvSlot26 END,
InvSlot27 = CASE WHEN InvSlot27 = 0 THEN 4 ELSE InvSlot27 END,
InvSlot28 = CASE WHEN InvSlot28 = 0 THEN 4 ELSE InvSlot28 END,
InvSlot29 = CASE WHEN InvSlot29 = 0 THEN 4 ELSE InvSlot29 END,
InvSlot30 = CASE WHEN InvSlot30 = 0 THEN 4 ELSE InvSlot30 END,
InvSlot31 = CASE WHEN InvSlot31 = 0 THEN 4 ELSE InvSlot31 END,
InvSlot32 = CASE WHEN InvSlot32 = 0 THEN 4 ELSE InvSlot32 END,
InvSlot33 = CASE WHEN InvSlot33 = 0 THEN 4 ELSE InvSlot33 END,
InvSlot34 = CASE WHEN InvSlot34 = 0 THEN 4 ELSE InvSlot34 END,
InvSlot35 = CASE WHEN InvSlot35 = 0 THEN 4 ELSE InvSlot35 END,
InvSlot36 = CASE WHEN InvSlot36 = 0 THEN 4 ELSE InvSlot36 END,
InvSlot37 = CASE WHEN InvSlot37 = 0 THEN 4 ELSE InvSlot37 END,
InvSlot38 = CASE WHEN InvSlot38 = 0 THEN 4 ELSE InvSlot38 END,
InvSlot39 = CASE WHEN InvSlot39 = 0 THEN 4 ELSE InvSlot39 END,
InvSlot40 = CASE WHEN InvSlot40 = 0 THEN 4 ELSE InvSlot40 END
WHERE Username = 'test' 

最佳答案

这是一个丑陋的黑客解决方案来完成你想要的事情。

首先,定义一个User-defined session variable以及您想要放入表中的值。

SET @x := 4;

然后像以前一样执行你的大 UPDATE 语句,但将槽设置为你的 @x 变量,并添加一些额外的内容:作为表达式的一部分,你还添加新赋值的结果使变量为零。添加零不会影响结果,但它会产生副作用,即 @x 的值更改为零,并且这将在后续槽分配中使用,直到查询结束。

只有先前为零的第一个槽才会触发更改 @x 的表达式,但任何后续为零的槽都会再次设置为零,这没有任何效果。

UPDATE userinfo SET
InvSlot1 = CASE WHEN InvSlot1 = 0 THEN @x+(@x:=0) ELSE InvSlot1 END,
InvSlot2 = CASE WHEN InvSlot2 = 0 THEN @x+(@x:=0) ELSE InvSlot2 END,
InvSlot3 = CASE WHEN InvSlot3 = 0 THEN @x+(@x:=0) ELSE InvSlot3 END,
InvSlot4 = CASE WHEN InvSlot4 = 0 THEN @x+(@x:=0) ELSE InvSlot4 END,
...

这是一个可能适用于您当前的数据库设计的技巧。

但是,我同意其他评论者对这个问题的看法,并且 your previous question ——你不应该以这种方式组织你的数据库。

相反,创建另一个表,每个用户最多包含 40 行。如果您在表中包含 userid 列,则不需要每个用户都有一个表,这样您就可以为每个用户重复 40 行,并指定哪些槽属于哪个用户。

要将槽限制为不超过 40,请创建一个查找表来枚举 40 行并使用外键约束。 (将来您只需向该表添加三行即可扩展到 43 个插槽。)

CREATE TABLE slots ( slot TINYINT PRIMARY KEY );
INSERT INTO slots (slot) VALUES (1), (2), (3), (4), ... 

CREATE TABLE userinfoInvslots (
  userid INT NOT NULL,
  slot TINYINT NOT NULL,
  slotvalue INT NOT NULL,
  PRIMARY KEY (userid, slot),
  FOREIGN KEY (slot) REFERENCES slots(slot)
);

现在,您不必为该插槽编号插入一行,而不是使用零来表示插槽未被占用。缺少行意味着该插槽未使用。清除槽可以通过删除该表中的一行来完成。

查询最低的未使用插槽很容易:

SELECT MIN(s.slot) AS minSlot
FROM slots AS s
LEFT OUTER JOIN userinfoInvslots AS u
  ON s.slot = u.slot and u.userid = 1234
WHERE u.slot IS NULL;
<小时/>

回复@CRSoftware33的评论

So if I have the users username as a primary key in my first table, would I use that in the second table as the primary key for that table?(I'm fairly new to SQL) and would I then only have two columns in my second table, one for the username and one for the int value that will be stored in the inventory slot?

我显示了一个列userid,假设您在 userinfo 表中有一个整数主键,但如果您将用户名作为主键,那么可以使用它。

I don't really know how I would make this work, because in my there are exactly forty slots, and in my GUI there are forty ImageViews which correspond to each slot in my inventory. How can I replicate this with two tables?

当您想要显示给定用户的槽位时,查询 userinfoInvslots 表 WHERE userid=? 并获取与您想要的用户对应的 40 行。然后在代码中循环这个结果集。当您获取行时,显示它们。

would there be a way to make a query that would generate the users inventory in my second table which consists of a username column, a slot column and an item id column? So in other words, it would be one query that would add forty rows and would add the users username for each column and would number their slot column from one to forty and would set each item id to zero for each row?

是的,您可以在 SQL 中执行此操作,但老实说,在应用程序代码中循环执行此操作更简单。使用循环变量从 1 计数到 40,并在循环的每次迭代中插入一行。我的意思并不是侮辱性的,但这确实是您在任何类(class)或任何书籍中学到的基本内容。

关于mysql - 如果满足其中一个 case 语句,如何结束 SQL case 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42614423/

相关文章:

php - 幸运抽奖概念 : SQL Query to get random option based on percentage of appearance

sql - PostgreSQL 在 3 个表上使用 JOIN 更新列

oracle - oracle中如何导出和导入BLOB数据类型

c# - 执行 pl/sql 查询时出现溢出错误

PHP连接两个表的帮助

mysql - 用于多个查找的 SSIS 派生列

php - 删除孤立记录 - mysql

mysql - SQL多对多查询返回false

mysql - 错误 1064 (42000) 未能授予权限

R 版本 4.0.0 上的 ROracle