8

2つのテーブルがあります。最初のテーブルは次のようになります。

表:レコード

    取り除く| ユーザーID| タイトル| 追加時| 公衆
-------------------------------------------------- ------------------
    1212例2012-06-281
    2 217 Test Rec 2012-07-05 1
    3212別の2012-07-021
    4212非公開2012-05-020
    5217成功2012-04-081
    6238常に2012-04-181

表:いいね

    id | ユーザーID| 取り除く| 好きなとき
-------------------------------------------------- --------
    1212 2 2012-07-06
    2205 1 2012-06-30
    3212 5 2012-07-04

'Records'テーブルでは、'rid'がプライマリインデックスとして設定されています。'Likes'テーブルでは、idがプライマリインデックスとして設定されています。

私はPHPを使用しています。PHPは、参照として使用する値をMySQLに提供します。次のことを行う単一のMySQLクエリが必要です。

擬似コード:

$userid = 212;
$SQL = 'SELECT DISTINCT records.* 
        FROM records,likes 
        WHERE (records.userid = ' . $userid . 
          ' AND records.public = 1) 
            OR (records.id = likes.rid AND likes.userid = ' . $userid . 
          ' AND records.public = 1) 
        ORDER BY likes.whenliked DESC, records.whenadded DESC 
        LIMIT 50;';

上で提供した$SQLクエリを見てください。それは私が望んでいたクエリを開発するための私の試みですが、それは私が探していたものを達成しませんでした。それはかなり近くに来ました、しかしそれはまだ間違った順序でした。クエリは、最初に自分でできる限り最善を尽くして開発され、次にStackFlowやGoogleの他の場所で解決策を検索して見つけたものに基づいて作成されました。

これらは私がそれを注文しようとしている条件です:

  1. 選択するすべてのレコードはパブリックである必要があります(records.public = 1)。
  2. レコードがユーザー(この例では212)に属している場合は、records.whenaddedでレコードを並べ替えます。
  3. レコードがユーザーのものではないが、ユーザーが気に入ったレコードである場合は、likes.whenlikedでレコードを並べ替えます。
  4. 日付は新しいものから古いものの順に並べられます。

返されるクエリの最終結果は次のようになります(returnedデータにlikedがない場合は、参照用にあるため、順序がわかります)。

    取り除く| ユーザーID| タイトル| 追加時| パブリック| 好きなとき{含まない}
-------------------------------------------------- ----------------------------------
    2 217 Test Rec 2012-07-05 1 2012-07-06
    3212別の2012-07-021
    5217成功2012-04-0812012-06-30
    1212例2012-06-281

それが理にかなっていることを願っています。お気軽にご質問ください。できる限りのことを明確にします。

あなたの時間、あなたの考慮、そしてこれを読んでくれてありがとう。返答がない、または解決策が見つからない場合でも、あなたの時間は非常にありがたいです!:)

4

4 に答える 4

4

注文するフィールドは、データベース内の既存のフィールドである必要はありません。選択で定義したフィールドを使用することもできます。

SELECT IF(records.userid = ' . $userid . ', records.whenadded, likes.whenliked) as date 

これで、パーツごとに使用できます。

ORDER BY date DESC

MySQLマニュアルから:

select_exprには、ASalias_nameを使用してエイリアスを指定できます。エイリアスは式の列名として使用され、GROUP BY、ORDER BY、またはHAVING句で使用できます。

于 2012-07-06T06:53:15.040 に答える
1

クエリを2つのクエリに分割し、代わりにUNIONを使用することをお勧めします。

SELECT * FROM(
(SELECT records.rid, records.userid,records.title, records.whenadded as adate
        FROM records,likes 
        WHERE records.userid =  $userid   AND records.public = 1 )
UNION
(SELECT records.rid, records.userid,records.title, likes.whenliked as adate 
        FROM records,likes 
        WHERE records.rid = likes.rid AND likes.userid = $userid  
          AND records.public = 1)
 )t ORDER BY adate DESC

編集済み: http://sqlfiddle.com/#!2/9a877/4を参照してください

于 2012-07-06T06:51:11.287 に答える
0

私のコメントによると、ここにあなたが見るべき別のクエリがあります:

SELECT
    records.*
FROM records
LEFT JOIN likes ON records.rid = likes.rid
WHERE records.public = 1
    AND COALESCE(likes.userid, records.userid) = $userid
ORDER BY COALESCE(likes.whenliked, records.whenadded) DESC;

それはあなたがレコードを2回以上好きになることができないと仮定して、奇妙なDISTINCTに乗ります。

COALESCEのドキュメントはこちらです。

このクエリは、実際にはパフォーマンス面ではありません。非常に大きなデータベースがある場合は、ユーザーIDのインデックスをフルパワーで使用するために、クエリを2つに分割してから、再度結合する方がよい場合があります。

于 2012-07-06T07:23:06.977 に答える
0

これはどう:

$userid = 212;
$SQL = 'SELECT DISTINCT records.* 
        FROM records,likes 
        WHERE (records.userid = ' . $userid . 
          ' AND records.public = 1) 
            OR (records.id = likes.rid AND likes.userid = ' . $userid . 
          ' AND records.public = 1) 
        ORDER BY records.userid, likes.whenliked DESC, records.whenadded DESC 
        LIMIT 50;';

これにより、最初にユーザーごとのレコードとユーザーごとのいいね!が日付で区切られます。

于 2012-07-06T06:56:47.387 に答える