mysql 具有多个WHERE的SQL查询

2j4z5cfb  于 2023-03-07  发布在  Mysql
关注(0)|答案(1)|浏览(135)

我有3个表。我想要一个t1.user_name,t3.item_id的列表,其中user_id = 17 AND stat = 0或者该行不存在,同时user_id!= 17 AND shipped = 1;
表一

CREATE TABLE table1(
    id NOT NULL AUTO_INCREMENT,
    user_name varchar(255),
);

表二

CREATE TABLE table2(
    id NOT NULL AUTO_INCREMENT,
    item_no varchar(255),
    item_name varchar(255),
);

表三

CREATE TABLE table3 (
  id int NOT NULL AUTO_INCREMENT,
  user_id int NOT NULL,
  item_id int NOT NULL,
  stat tinyint NOT NULL,
  shipped tinyint NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (user_id) REFERENCES table1(id),
  FOREIGN KEY (item_id) REFERENCES table2(id)
);

在user_id!= 17且shipped = 1的情况下,我设法列出了我想要的一半内容,但如果user = 17且stat = 1,我无法隐藏item_id。

SELECT 
t3.user_id AS 'User_ID',
t1.username AS 'Username',
GROUP_CONCAT(t3.item_id ORDER BY t3.item_id ASC) AS 'Item List'
from table3 t3
inner join table2 t2 on t2.id=t3.item_id
inner join accounts t1 on t1.id=t3.user_id
WHERE user_id != 17 AND t3.shipped=1
group by t3.user_id
ORDER BY COUNT('Item_List') DESC;

另外,如果用户没有NULL值,我不知道如何获取NULL值的行,因此t3中甚至没有NULL值的行。
用户1的item_id为1、2、3、4、5,发货次数为6、7、8、9。
用户17没有发货6、7、8、9,但发货了1、2、3、4、5。
结果应该是这样的
| 用户名|已装运|
| - ------|- ------|
| 用户1|六、七、八、九|
我希望我把我的问题解释清楚了
谢谢大家!

jtw3ybtb

jtw3ybtb1#

首先,* 但如果user=17且stat=1,则无法隐藏item_id *
听起来你是在说,我有两个案子;一个userid不是17,另一个userid是17。您已经将“not 17”作为user_id != 17 AND t3.shipped=1。现在添加所需的“is 17”大小写,t3.id=17 AND t1.stat!=1带有OR条件:

Where (t3.id != 17 AND t1.shipped=1)
   OR (t3.id=17 AND t1.stat!=1)

括号更多的是为了可读性,因为AND运算符比OR运算符具有更高的优先级,如果不使用括号,则会得到相同的逻辑和相同的结果。
其次,* 另外,如果用户没有NULL值,我不知道如何获取该行 *
您需要使用OUTER JOIN将table 2联接到table 3,以获取没有产品的用户。INNER联接和OUTER联接之间的区别在于,内部联接仅包括现有行,而外部联接保留所有行并为缺少的数据创建NULL值。您还需要重新排列表顺序以获取正确的NULL集:

From table3 t3 Left Outer Join
     table1 t1 On t1.id=t3.userid Inner Join
     table2 t2 On t2.id=t3.item_id

但是这还不够,你的Where子句包含了t3.shipped=1,当没有产品时,它将为NULL,并且不会被选中。你需要在你的Where子句中添加第三个项t1.user_id is null,所以完整地说,

Where (t3.id != 17 AND t1.shipped=1)
   OR (t3.id=17 AND t1.stat!=1)
   OR (t1.user_id is null)

,这应该可以了。

相关问题