【发布时间】:2013-09-21 20:54:58
【问题描述】:
我已经重新设计了我的数据库结构,以使用主键和外键将我的 3 个表中的条目链接在一起,但在给定另一个表中的数据的情况下,我在尝试编写查询以选择一个表中的数据时遇到问题。这是我的 3 个 CREATE TABLE 语句的示例:
CREATE TABLE IF NOT EXISTS players (
id INT(10) NOT NULL AUTO_INCREMENT,
username VARCHAR(16) NOT NULL,
uuid VARCHAR(200) NOT NULL DEFAULT 0,
joined TIMESTAMP DEFAULT 0,
last_seen TIMESTAMP DEFAULT 0,
PRIMARY KEY (id)
);
/* ^
One |
To
| One
v
*/
CREATE TABLE IF NOT EXISTS accounts (
id INT(10) NOT NULL AUTO_INCREMENT,
account_id INT(10) NOT NULL,
pass_hash VARCHAR(200) NOT NULL,
pass_salt VARCHAR(200) NOT NULL,
created BIGINT DEFAULT 0,
last_log_on BIGINT DEFAULT 0,
PRIMARY KEY (id),
FOREIGN KEY (account_id) REFERENCES players(id) ON DELETE CASCADE
) ENGINE=InnoDB;
/* ^
One |
To
| Many
v
*/
CREATE TABLE IF NOT EXISTS purchases (
id INT(10) NOT NULL AUTO_INCREMENT,
account_id INT(10) NOT NULL,
status VARCHAR(20) NOT NULL,
item INT NOT NULL,
price DOUBLE DEFAULT 0,
description VARCHAR(200) NOT NULL,
buyer_name VARCHAR(200) NOT NULL,
buyer_email VARCHAR(200) NOT NULL,
transaction_id VARCHAR(200) NOT NULL,
payment_type VARCHAR(20) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (account_id) REFERENCES accounts(account_id) ON DELETE CASCADE
) ENGINE=InnoDB;
例如,我想选择购买超过 30 美元商品的用户的所有用户名。所有用户名都存储在 player 表中,该表链接到 accounts 表并链接到 purchase 表。这是设计这个关系数据库的最佳方式吗?如果是这样,我将如何运行类似于上述示例的查询?
我能够根据用户名获取所有用户的购买历史记录,但我使用 2 个子查询来完成此操作...获取该数据应该比这更容易! 这是我为获取所有玩家购买数据而运行的 SELECT 查询:
SELECT *
FROM purchases
WHERE account_id = (SELECT id FROM accounts WHERE account_id = (SELECT id FROM players WHERE username = 'username'));
此外,当我尝试使用“players.username”之类的内容引用其他表时,我收到一条错误消息,指出该列不存在...
感谢您的帮助!谢谢!
【问题讨论】:
-
@Sam 哇,我应该知道加入与此有关!我应该做更多的研究!感谢您的链接!我能够使用内部连接查询我在问题中提供的示例: SELECT username FROM player INNER JOIN accounts ON player.id= accounts.account_id INNER JOIN purchase ON accounts.id = purchase.account_id WHERE purchase.price >= 30;
-
好吧,每个人都开始一次:)。该查询本身看起来是正确的,但是,您只是加入 一次 购买,因此您可能会错过价格 > 30 的购买(我假设是一对多的关系)。这些购买的子选择可以做到这一点,或者,您可以使用右外连接和不同的,或者简单地将
price > 30条件放入购买的连接谓词中