英文:
SQL - Rows not exist as exist
问题
我有3个表。一个包含用户列表,一个包含物品,一个包含用户和物品之间的关系。用户可以拥有一个物品(stat = 0/1),或者可以有一个重复的物品(dup = 0/1)。如果你点击物品或重复按钮,它会运行一个查询,添加或更新行。
表格看起来像这样:
| user | item_id | stat | dup |
| ---- | ------- | ---- | --- |
| 17 | 1 | 1 | 1 |
| 5 | 2 | 1 | 0 |
| 8 | 1 | 0 | 1 |
| 9 | 4 | 1 | 0 |
我用以下查询比较这些数据,找出哪些用户有一个物品而另一个用户没有,反之亦然:
SELECT t2.user_id,
GROUP_CONCAT(CASE WHEN t1.dup=1 AND t2.stat=0 THEN item_id END) `My Item List`,
GROUP_CONCAT(CASE WHEN t2.dup=1 AND t1.stat=0 THEN item_id END) `Item List`
FROM table3 t1
LEFT JOIN table3 t2 USING (item_id)
WHERE t1.user_id = @current_user
AND t2.user_id <> @current_user
GROUP BY t2.user_id
我的问题是,我只能比较用户至少点击过一次物品按钮的行,所以只生成了这样的行,但是我需要stat=0的行,即使它们不存在。
代码运行后,表格应该像这样,这样我就可以看到关系,即使用户没有(stat=0)那个物品:
| user | item_id | stat | dup |
| ---- | ------- | ---- | --- |
| 17 | 1 | 1 | 1 |
| 5 | 2 | 0 | 0 |
| 5 | 6 | 1 | 0 |
| 8 | 1 | 0 | 1 |
| 9 | 4 | 1 | 0 |
| 9 | 6 | 0 | 0 |
| 17 | 13 | 0 | 0 |
我应该如何将这些集成到上面的查询中?
我的表格:
表格1
CREATE TABLE table1(
id NOT NULL AUTO_INCREMENT,
user_name varchar(255),
);
表格2
CREATE TABLE table2(
id NOT NULL AUTO_INCREMENT,
item_no varchar(255),
item_name varchar(255),
item_group varchar(255)
);
表格3
CREATE TABLE table3 (
id int NOT NULL AUTO_INCREMENT,
user_id int NOT NULL,
item_id int NOT NULL,
stat tinyint NOT NULL,
dup tinyint NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES table1(id),
FOREIGN KEY (item_id) REFERENCES table2(id)
);
谢谢!
英文:
I have 3 tables. One with a list of users, one with items and one with relation between the users and the items. User can have an item (stat = 0/1) or can have a duplicate (dup = 0/1). If you click on the item's or the duplicate's button, it runs a query that adds or updates the row.
It looks like this:
| user | item_id | stat | dup |
| ---- | ------- | ---- | --- |
| 17 | 1 | 1 | 1 |
| 5 | 2 | 1 | 0 |
| 8 | 1 | 0 | 1 |
| 9 | 4 | 1 | 0 |
I compare these data who have an item what the other does not have and vica versa with this query:
SELECT t2.user_id,
GROUP_CONCAT(CASE WHEN t1.dup=1 AND t2.stat=0 THEN item_id END) `My Item List`,
GROUP_CONCAT(CASE WHEN t2.dup=1 AND t1.stat=0 THEN item_id END) `Item List`
FROM table3 t1
LEFT JOIN table3 t2 USING (item_id)
WHERE t1.user_id = @current_user
AND t2.user_id <> @current_user
GROUP BY t2.user_id
My problem is I can only compare the rows if the user already clicked the button of the item at least once, so the row generated, but I need the stat=0 rows as well even if they are not existing.
After the code runs the table should look like this, so I can see the relations even if the user doesnt have (stat=0) that item:
| user | item_id | stat | dup |
| ---- | ------- | ---- | --- |
| 17 | 1 | 1 | 1 |
| 5 | 2 | 0 | 0 |
| 5 | 6 | 1 | 0 |
| 8 | 1 | 0 | 1 |
| 9 | 4 | 1 | 0 |
| 9 | 6 | 0 | 0 |
| 17 | 13 | 0 | 0 |
How can I integrate this to the query above?
My tables:
Table1
CREATE TABLE table1(
id NOT NULL AUTO_INCREMENT,
user_name varchar(255),
);
Table 2
CREATE TABLE table2(
id NOT NULL AUTO_INCREMENT,
item_no varchar(255),
item_name varchar(255),
item_group varchar(255)
);
Table 3
CREATE TABLE table3 (
id int NOT NULL AUTO_INCREMENT,
user_id int NOT NULL,
item_id int NOT NULL,
stat tinyint NOT NULL,
dup tinyint NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES table1(id),
FOREIGN KEY (item_id) REFERENCES table2(id)
);
Thank you!
答案1
得分: 0
如果你只获取用户和item_id的所有唯一组合,然后只映射存在的组合,将其余部分设为null,然后用0替换null,会怎样?
类似这样,
SELECT
all_combos.user,
all_combos.item_id,
COALESCE(T.stat, 0) AS stat,
COALESCE(T.dup, 0) AS dup
FROM
(
SELECT
user,
item_id
FROM
(SELECT DISTINCT user FROM table3) u,
(SELECT DISTINCT item_id FROM table3) i
) AS all_combos
LEFT OUTER JOIN table3 T ON T.user = all_combos.user
AND T.item_id = all_combos.item_id
如果你想创建用户和项目的组合,这些组合在table3中可能从未发生过,你可以通过修改`u`和`i`子查询来合并它们。
SELECT
all_combos.user,
all_combos.item_id,
COALESCE(T.stat, 0) AS stat,
COALESCE(T.dup, 0) AS dup
FROM
(
SELECT
user,
item_id
FROM
(SELECT DISTINCT id as user FROM table1) u,
(SELECT DISTINCT id as item_id FROM table2) i
) AS all_combos
LEFT OUTER JOIN table3 T ON T.user = all_combos.user
AND T.item_id = all_combos.item_id
英文:
What if you just grab all unique combinations of user and item_id, and then only map the combinations present and leave the rest as null? We can replace the null with 0.
Something like,
SELECT
all_combos.user,
all_combos.item_id,
COALESCE(T.stat, 0) AS stat,
COALESCE(T.dup) AS dup
FROM
(
SELECT
user,
item_id
FROM
(SELECT DISTINCT user FROM table3) u,
(SELECT DISTINCT item_id FROM table3) i
) AS all_combos
LEFT OUTER JOIN table3 T ON T.user = all_combos.user
AND T.item_id = all_combos.item_id
If you want to create combinations of users and items that might not have ever happened in table3, you can combine them by modifying the subqueries for u
and i
SELECT
all_combos.user,
all_combos.item_id,
COALESCE(T.stat, 0) AS stat,
COALESCE(T.dup) AS dup
FROM
(
SELECT
user,
item_id
FROM
(SELECT DISTINCT id as user FROM table1) u,
(SELECT DISTINCT id as item_id FROM table2) i
) AS all_combos
LEFT OUTER JOIN table3 T ON T.user = all_combos.user
AND T.item_id = all_combos.item_id
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论