1

何時間にもわたって自分で調べたり試したりした後、ついに Stackoverflow に登録しました。このような学びの機会をありがとうございました!私は今、解決できないMySQLの問題の助けを見つけたいと思っています. 私は立ち往生しています。

出典:顧客による注文の表があります。

出力:メール アドレスごとにグループ化された注文が必要です。メール アドレスごとに、総売上高の合計、注文数、作成された最初の注文と最後に作成された注文の行が必要です。ここまでは、グループ化と min() および max() 関数によって実行できました。私が立ち往生しているところ:最初と最後の注文のIPアドレス、最初と最後の注文の名など(さらに下の目的の出力を参照)が必要です。

私が試して調査したこと: Groupwise max、サブセレクト内の順序とグループ外のサブセレクト、いくつかの結合バリアント。

これは、ランダム データを使用した SQLfiddle と、私が作成した SQL クエリです。次のように機能します: http://sqlfiddle.com/#!9/0272b/6

SQLfiddle の SQL の代わりに、これを試してみました。これは、1 つの電子メール アドレスに対して機能します。

SELECT
    lastentry.entity_id,
    lastentry.customer_email,
    firstentry.created_at AS FirstOrder,
    lastentry.created_at  AS LastOrder,
    COUNT(lastentry.entity_id) AS TotalOrders,
    SUM(lastentry.grand_total) AS TotalTurnover,
    firstentry.entity_id,
    firstentry.remote_ip AS FirstIP,
    lastentry.remote_ip  AS LastIP
FROM
    orders lastentry
LEFT OUTER JOIN
    (
        SELECT
            co1.entity_id,
            co1.customer_email,
            co1.remote_ip,
            co1.created_at
        FROM
            orders AS co1,
            (
                SELECT
                    customer_email,
                    remote_ip,
                    MIN(created_at) AS maxpop
                FROM
                    orders
                GROUP BY
                    customer_email) AS co2
        WHERE
            co2.customer_email = co1.customer_email
        AND co1.created_at = co2.maxpop ) AS firstentry
ON
    (
        lastentry.customer_email = firstentry.customer_email )
ORDER BY
    lastentry.created_at DESC,
    firstentry.created_at ASC
LIMIT 1

また、where ステートメントで subselect を使用して subselect または join を実行しようとしましたが、うまくいきませんでした。

created_at = (SELECT MAX(t2.created_at)
    FROM orders t2
    WHERE customer_email= t1.customer_email
)

私の実際の望ましい出力は次のようになります。

| customer_email           | FirstOrder          | LastOrder           | TotalOrders | TotalTurnover | FirstIP       | LastIP         | FirstName | LastName |
|--------------------------|---------------------|---------------------|-------------|---------------|---------------|----------------|-----------|----------|
| darmstrong3@skype.com    | 2014-11-06 16:38:31 | 2014-11-15 11:14:42 | 2           | 116,09        | 103.132.17.9  | 153.241.73.137 | David     | David    |
| fthompson0@moonfruit.com | 2014-08-19 06:26:26 | (null)              | 1           | 1,1           | 87.217.157.91 | (null)         | Frank     | (null)   |
| jrice2@icq.com           | 2014-06-01 09:59:10 | (null)              | 1           | 95,76         | 117.4.9.206   | (null)         | Joshua    | (null)   |
| kphillips8@oracle.com    | 2015-01-30 22:49:56 | (null)              | 1           | 57,12         | 220.77.70.87  | (null)         | Kevin     | (null)   |
| lcruz5@techcrunch.com    | 2014-10-27 01:02:46 | (null)              | 1           | 90,45         | 122.38.175.17 | (null)         | Larry     | (null)   |
| scarpenter1@salon.com    | 2012-11-05 07:56:38 | 2014-06-09 21:57:20 | 3           | 163,58        | 220.75.17.164 | 203.81.207.35  | Steven    | Lousie   |

どんな助けでも大歓迎です!


自問自答する質問:

  • これはMySQLで解決できますか? Excel では、ピボット テーブルを簡単に作成できました。
  • そうでない場合は、ストアド プロシージャを使用して解決できますか? すべてのレコードをループし、注文が 1 つしかない場合はフィールドをスキップしますか?
4

2 に答える 2

0

substring_index()/group_concat()トリックを使用することをお勧めします。次のようになります。

SELECT o.entity_id, o.customer_email,
       min(created_at) AS FirstOrder, max(created_at)  AS LastOrder,
       count(*) AS TotalOrders, sum(o.grand_total) AS TotalTurnover,
       substring_index(group_concat(remote_ip order by created at), ',', 1) as first_ip,
       substring_index(group_concat(remote_ip order by created at desc), ',', 1) as last_ip
FROM orders o
GROUP BY o.entity_id, o.customer_email;

これは、妥当なデータに対して機能するはずです。の中間結果の長さには構成可能な制限がありますgroup_concat()

于 2015-03-11T11:30:01.903 に答える
0

サブクエリを使用して、最初と最後の注文の行の値を見つけることもできます。これは、最初と最後の注文が entity_id に基づいていることを前提としています。

SELECT 
   customer_email, 
   COUNT(*) AS total_orders, 
   SUM(grand_total) AS total_turnover,
   (SELECT created_at FROM orders WHERE 
       entity_id = MIN(t.entity_id)) AS first_created_at,
   (SELECT created_at FROM orders WHERE 
       entity_id = MAX(t.entity_id)) AS last_created_at,
   (SELECT remote_ip FROM orders WHERE 
       entity_id = MIN(t.entity_id)) AS first_remote_ip,
   (SELECT remote_ip FROM orders WHERE 
       entity_id = MAX(t.entity_id)) AS last_remote_ip,
   (SELECT customer_firstname FROM orders WHERE 
       entity_id = MIN(t.entity_id)) AS first_customer_firstname,
   (SELECT customer_firstname FROM orders WHERE 
       entity_id = MAX(t.entity_id)) AS last_customer_firstname
FROM orders AS t
GROUP BY customer_email
于 2015-03-11T11:47:17.447 に答える