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 と呼ばれるものが 1 つではなく 5 つ含まれています。a.userId、b.userId、c.userId、d.userId、および e.userId があります。そのため、userId を参照する場合、どれを参照するかはあいまいです。それが a.userId の場合は正しいです。空白にすることはできません。他のいずれかの場合、左結合から欠落しているため、空白になる可能性があります。

必要な a.userId を参照していることを確認するには、明示的に選択して、あいまいさなく参照できるようにします。私が入れたサンプルコードでは、「すべて」に加えてそれを選択し、明示的に名前を付けて、「信頼できる」a.userIdを参照していることを確認できるようにします。

于 2013-07-26T09:41:55.657 に答える