【问题标题】:SQL query from multiple tables with missing fields来自多个缺少字段的表的 SQL 查询
【发布时间】:2017-09-08 00:10:52
【问题描述】:

希望有人可以帮助我。我有 5 个表格,简化示例如下:

catalog_items:在目录中存储有关项目的信息。

CREATE TABLE catalog_items (
  item_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  title VARCHAR(255) NOT NULL,
  create_date DATETIME NOT NULL,
  valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,

  PRIMARY KEY (item_id)
);

用户:存储用户信息。

CREATE TABLE users (
  user_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  email VARCHAR(255) NOT NULL,
  valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,

  PRIMARY KEY (user_id)
);

user_contribution_types:用户可以向目录贡献项目以赚取积分,此表描述了贡献的类型以及他们赚取的金额。

CREATE TABLE user_contribution_types (
  type_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  description TEXT NOT NULL,
  credits DECIMAL(5,2) UNSIGNED NOT NULL,
  valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,

  PRIMARY KEY (type_id)
);

user_contributions:将上述所有内容关联起来的表格(哪个用户贡献了 x 项)。

CREATE TABLE user_contributions (
  user_id INTEGER UNSIGNED NOT NULL,
  item_id INTEGER UNSIGNED NOT NULL,
  type_id INTEGER UNSIGNED NOT NULL,
  create_date DATETIME NOT NULL,
  valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,

  FOREIGN KEY (user_id)
    REFERENCES users(user_id),
  FOREIGN KEY (item_id)
    REFERENCES catalog_items(item_id),
  FOREIGN KEY (type_id)
    REFERENCES user_contribution_types(type_id)
);

pending_items:所有贡献都必须经过批准,因此它们存储在临时表中。 这些条目可能来自还没有帐户的新用户,这就是为什么只有一封电子邮件而不是user_id

CREATE TABLE pending_items (
  pending_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  email VARCHAR(255) NOT NULL,
  title VARCHAR(255) NOT NULL,
  create_date DATETIME NOT NULL,
  valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,

  PRIMARY KEY (pending_id)
);

问题

我正在尝试从目录中选择已批准和待处理的项目;但是,到目前为止我想出的最好的方法是将它们分开:

仅选择已批准的贡献:

SELECT a.item_id, c.title, a.create_date, b.description, b.credits
FROM user_contributions a, user_contribution_types b, catalog_items c
WHERE a.type_id = b.type_id AND a.item_id = c.item_id
AND a.valid = TRUE AND b.valid = TRUE AND c.valid = TRUE
ORDER BY c.create_date DESC LIMIT 0, 10

仅选择待处理的贡献:

SELECT pending_id, title, create_date FROM pending_items WHERE email = 'example@email.com' AND valid = TRUE
ORDER BY create_date DESC LIMIT 0, 10

有没有办法将上述 2 个查询组合起来得到如下结果集,其中缺少的字段仅显示为 NULL

| item_or_pending_id | title | create_date         | description | credits | approved |
| ------------------ | ----- | ------------------- | ----------- | ------- | -------- |
| 14                 | test4 | 2017-04-08 04:41:21 | bar         | 1.00    | true     |
| 14                 | test3 | 2017-04-06 01:23:45 | NULL        | NULL    | false    |
| 11                 | test2 | 2017-02-03 12:30:00 | NULL        | NULL    | false    |
| 9                  | test1 | 2017-01-25 05:16:18 | foo         | 1.00    | true     |

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    是的:-)

    SELECT a.item_id AS item_or_pending_id, 
           c.title, 
           a.create_date, 
           b.description, 
           b.credits, 
           true      AS approved 
    FROM   user_contributions a, 
           user_contribution_types b, 
           catalog_items c 
    WHERE  a.type_id = b.type_id 
           AND a.item_id = c.item_id 
           AND a.valid = true 
           AND b.valid = true 
           AND c.valid = true 
    UNION 
    SELECT pending_id, 
           title, 
           create_date, 
           NULL, 
           NULL, 
           false 
    FROM   pending_items 
    WHERE  email = 'example@email.com' 
           AND valid = true 
    ORDER  BY create_date DESC 
    LIMIT  0, 10 
    

    【讨论】:

    • 谢谢。我试试看!
    • 为什么有人会赞成在FROM 子句中使用逗号的答案?
    • 对不起,我把原来的查询改到了最低限度。我不应该重构他的工作。因此,既然它似乎需要澄清,想知道的人可能会在stackoverflow.com/a/11180050/1291428
    • 所以,要重构我应该用JOIN...ONs 替换WHERE 子句?
    • @mistermartin 用连接替换逗号是的。您仍然可能希望在 where 子句中保留一些过滤器,例如 email 和 valid
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2020-09-29
    • 1970-01-01
    相关资源
    最近更新 更多