SQL – 行不存在如存在

huangapple go评论98阅读模式
英文:

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 &lt;&gt; @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

huangapple
  • 本文由 发表于 2023年4月17日 19:13:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76034540.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定