1

加强我的 PostgreSQL 知识。这是一个有效的查询:

SELECT * 
FROM associates a 
    LEFT OUTER JOIN ip b 
         ON a.userID = b.userID AND b.iPAddress = '124.xxx.xxx.xxx' 
    LEFT OUTER JOIN browser c 
         ON a.userID = c.userID AND c.userAgent = 'Mozilla / whatever Gecko' 
    LEFT OUTER JOIN location d 
         ON a.userID = d.userID AND d.country = 'US' 
    LEFT OUTER JOIN session e 
         ON a.userID = e.userID AND e.lastAction >= now() - interval '24 hours' 
WHERE a.extensionID = 'xxxxx' 
LIMIT 1

运行这个,假设所有条件都满足,返回一个不错的哈希值,{'userid' => 12345, ... }我以后可能想使用它(例如,如果一个会话已经过期,我需要它来创建一个新的)

但是,在任何不匹配的情况下——例如——如果调用用户的 IP 被更改——将导致相同的散列但丢失数据,更重要的是,散列将以{'userid' => nil}

说的userID明明是用来匹配其他表的,为什么会丢失,更重要的是如何保存呢?

这是有道理的,有点:如果存在不匹配,则不会“选择”任何内容。有没有办法以某种方式保留原件a.userID

我应该提到我正在通过 pg gem使用 Heroku 的 PostgreSQL 。

4

2 回答 2

3

永远不要在生产代码中使用 *,它很容易出错。列userid存在于所有表中,但你需要哪一个?只需提及您真正需要的列,并在需要时使用别名。

于 2013-07-26T09:45:57.037 回答
2

想知道是否可能从另一个表(b.userID,c.userId,...)中获取用户 ID。尝试明确选择并更改名称。

SELECT a.userID As MainUserId, * FROM associates a ...

因此,在“*”所有字段中,您拥有的不是一个而是五个称为 userId 的东西。您有 a.userId、b.userId、c.userId、d.userId 和 e.userId。因此,当您提到 userId 时,它所指的是哪一个是模棱两可的。如果它是 a.userId 那么你是对的,它不应该是空白的。如果其中之一,它可能是空白的,因为缺少左连接。

为确保您引用的是所需的 a.userId,请明确选择它,以便您可以毫无歧义地引用它。在我放置的示例代码中,除了“一切”之外,我还选择了它并明确命名,这样您就可以确定您指的是“可靠”的 a.userId。

于 2013-07-26T09:41:55.657 回答