2

特定の期間の関連する価格とともに、すべての製品のリストを取得したいと考えています。

製品テーブル:

Id
Name
Description

価格表:

Id 
Product_id
Name
Amount
Start
End
Duration

ここで注意すべき最も重要なことは、製品は同じ期間であっても複数の価格を持つことができますが、同じ期間ではないということです。たとえば、「2013-06-01 -> 2013-06-08」の価格と「2013-06-01 -> 2013-06-05」の別の価格

したがって、私の目的は、特定の期間、たとえば 10 個の製品でページ分割されたすべての製品のリストを、その期間中に存在する価格に結合して取得することです。

そのための基本的な方法は次のとおりです。

SElECT *
FROM product
LEFT JOIN prices ON ...
WHERE prices.start >= XXX And prices.end <= YYY
LIMIT 0,10

この単純なソリューションを使用する際の問題は、10 個の製品のみを取得することはできず、10 個の製品 * 価格を取得できないことです。これは私の場合は受け入れられません。

したがって、解決策は次のようになります。

SElECT *
FROM product
LEFT JOIN prices ON ...
WHERE prices.start >= XXX And prices.end <= YYY
GROUP BY product.id
LIMIT 0,10

しかし、ここでの問題は、各製品の「1」の価格しか取得しないことです。

ですから、これを処理する最善の方法は何だろうかと思います。たとえば、「group_concat」などのグループ関数を使用して、「200/300/100」などの文字列内のすべての価格をフィールドで取得できます。それは奇妙に思え、サーバー言語側で読み取り可能な情報に変換する必要がありますが、うまくいく可能性があります。

別の解決策は、期間に応じて、価格ごとに異なる列を使用することです。

SELECT 
   IF( NOT ISNULL(price.start) AND price.duration = 1, price.amount , NULL) AS price_1_day
   ---- same here for all possible durations ---
From ...

Thtaもうまくいくと思いますが(これが可能かどうかはよくわかりません)、すべての可能性をカバーするには約250列を作成する必要があるかもしれません. それは安全なオプションですか?

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

4

2 に答える 2

1

group_concat は、特定の列に関連する複数のデータを集約することを目的としているため、これを進める最善の方法であると考えています。

ただし、peterm の SQL フィドルに適応すると、ユーザー定義変数を使用する場合、これは 1 つのクエリで実行できます。(変数を設定するための最初のクエリを無視した場合)

http://dev.mysql.com/doc/refman/5.7/en/user-variables.html

SET @productTemp := '', @increment := 0;

SElECT
  @increment := if(@productTemp != Product_id, @increment + 1, @increment) AS limiter,
  @productTemp :=Product_id as Product_id,
  Product.name,
  Price.id as Price_id,
  Price.start,
  Price.end
FROM 
  Product
LEFT JOIN
  Price ON Product.Id=Price.Product_id
WHERE 
  `start` >= '2013-05-01' AND `end` <= '2013-05-15'
GROUP BY
 Price_id
HAVING 
  limiter <=2

ここで行っているのは、製品 ID が最後に検出されたものと同じでない場合にのみ、ユーザー定義の var "incrementer" をインクリメントすることだけです。

エイリアスは WHERE 条件で使用できないため、HAVING を使用して結果を削減できるように、一意の ID (この場合は価格 ID) でグループ化する必要があります。この場合、3 つの製品 ID を含む必要がある完全な結果セットがあり、2 つしか表示されません。

注意: これは、大規模なデータ セットや本番環境で推奨するソリューションではありません。mysql のマニュアルでさえ、オプティマイザーが取るパスに応じて、ユーザー定義の変数が多少不規則に動作する可能性があることを強調しています。ただし、過去にいくつかの内部統計に大きな効果をもたらすためにそれらを使用しました。

フィドル: http://sqlfiddle.com/#!2/96c92/3

于 2013-06-07T09:43:39.093 に答える
0

サンプルデータと目的の出力がないとわかりにくいですが、このようなことを試すことができます

SElECT p.*, q2.*
  FROM 
(
  SElECT Product_id
    FROM Price
   WHERE `start` >= '2013-05-01' AND `end` <= '2013-05-15'
   GROUP BY Product_id
  LIMIT 0,10
) q1 JOIN 
(
    SELECT *
      FROM Price
     WHERE `start` >= '2013-05-01' AND `end` <= '2013-05-15'
) q2 ON q1.Product_id = q2.Product_id JOIN product p
     ON q1.Product_id = p.Id

これがSQLFiddleのデモです

于 2013-06-07T09:09:07.357 に答える