4

私は3つのテーブルを持っています。PRICE3つの異なるテーブルを使用してフィールドの違いを見つける良い方法を探し、次に上位3つの最大の負の違いを表示します。まず、使用するのに最適なMySQLクエリを見つけ、それをすべてphpで表示するための最良の方法を見つけたいと思います。

メンテナンス可能:

COMPANY       | MODEL    | PRICE
Main Company  | ProductA | 100.00
Main Company  | ProductB | 50.00
Main Company  | ProductC | 25.00
Main Company  | ProductD | 300.00

COMPTABLE1:

COMPANY     | MODEL    | PRICE
Competitor1 | ProductA | 100.00 //0
Competitor1 | ProductB | 55.00 //5
Competitor1 | ProductC | 50.00 //25
Competitor1 | ProductD | 200.00 //-100

COMPTABLE2:

COMPANY     | MODEL    | PRICE
Competitor2 | ProductA | 99.00 //-1
Competitor2 | ProductB | 44.00 //-6
Competitor2 | ProductC | 20.00 //-5
Competitor2 | ProductD | 100.00 //-200

したがって、自分のページに表示したいPRICEの最大のマイナスの違いは次のとおりです。

  1. Competitor2ProductD-メイン会社のProductDとの200の違い
  2. Competitor1ProductD-メイン会社のProductDとの100の違い
  3. 競合他社2ProductB-6メインカンパニーProductBとの違い

IDEA:私はあまり馴染みがありませんがUNION SELECT、3つのテーブルで..を使用できますWHERE MODEL=XXX。私はおそらく、データを収集し、計算を行い、情報を吐き出すそれぞれをループすることができます。唯一の問題は、各テーブルの独自の価格として各変数を格納する方法がわからないことです。また、計算を行った後に各変数を格納し、上位3つの差異を表示する方法がない限り、すべての差異が表示されると思います。

このクエリに最もよく取り組むためのアイデアや提案をいただければ幸いです。(注:いいえ、すべてを1つのテーブルに入れることはできません= p)

4

4 に答える 4

5

PHP側では役に立ちませんが、このクエリで必要なものが得られるはずです。適格な結果をすべて得るには、結合を行う必要があります。これにより、すべての列が使用可能になり、事前に計算されて、必要な方法で単純なグリッドリストに配置できます。計算は競合他社と主要企業であるため、自然順序によるPriceDifferenceは、最初に最大の負の値を持ち、次に正の値になります。したがって、LIMITコマンドは注文後に適用され、3つのレコードを送り返すだけです。

select 
      MT.Model,
      MT.Company as MainCompany,
      MT.Price as MainPrice,
      CT1.Company as Competitor,
      CT1.Price as CompPrice,
      CT1.Price - MT.Price as PriceDifference
   from
      MainTable MT
         JOIN CompTable1 CT1
            on MT.Model = CT1.Model
UNION
select 
      MT.Model,
      MT.Company as MainCompany,
      MT.Price as MainPrice,
      CT2.Company as Competitor,
      CT2.Price as CompPrice,
      CT2.Price - MT.Price as PriceDifference
   from
      MainTable MT
         JOIN CompTable2 CT2
            on MT.Model = CT2.Model
order by
   PriceDifference
limit 3

提案...テーブルを構造化する方法は、長期的には非常に悪いものです。より最適なパフォーマンスを得るには、データを正規化するようにしてください。100人の競合他社がいる場合はどうなりますか。あなたはいたるところに重複があります。モデル名も変更してください。これが私がテーブルを再構築する方法です...明示的なデータ入力ではなく、概念的に

COMPANY 
   CompanyID     auto-increment
   CompanyName   character

PRODUCT
   ProductID     auto-increment
   ProductModel  character

VendorPricing
   VPriceID      auto-increment
   CompanyID     (ID pointing to company table -- to get name when needed)
   ProductID     (ID pointing to product table -- to get model name too)
   Price         actual price for this particular company and product

次に、適切なインデックスを使用して、あるベンダーから別のベンダーへの価格設定を取得したい場合、およびどのモデルでも、クエリは将来拡張しやすくなる可能性があります...

select 
      VP1.CompanyID,
      C1.CompanyName as MainCompany,
      C2.CompanyName as Competitor,
      P1.ProductModel,
      VP1.Price as MainPrice,
      VP2.Price as CompetitorPrice,
      VP2.Price - VP1.Price as PriceDifference
   from
      VendorPricing VP1

         JOIN Company C1
            on VP1.CompanyID = C1.CompanyID

         JOIN Product P1
            on VP1.ProductID = P1.ProductID

         JOIN VendorPricing VP2
            on VP1.ProductID = VP2.ProductID
           AND NOT VP1.CompanyID = VP2.CompanyID

           JOIN Company C2
              on VP2.CompanyID = C2.CompanyID

   where
      VP1.CompanyID = TheOneCompanyYouAreInterestedIn
   order by
      PriceDifference
   limit 3

したがって、2、5、10、または100人の競合他社がいる場合、クエリはまったく同じです。

于 2012-04-25T17:05:41.120 に答える
1
select mt1.company, tt1.company, mt1.price, tt1.price, (mt1.price - tt1.price) as delta
from mt1
    -- treats tables as single table and allows you flexibility to add more later
    left join (
    select company, model, price from t1
    union
    select company, model, price from t2
    ) tt1 on tt1.model = mt1.model
order by  (mt1.price - tt1.price) 
limit 3 -- actually should be parameter to sproc

nullと欠落値について考える必要があります。あなたは何も指定しなかったので、私もそれらを処理しませんでした。

誰かが以前、計算を行うmysqlのパフォーマンスが悪いと述べました。この種のことは、まさにデータベースが行うように設計されたものです。mysqlのパフォーマンスの低下は、それが「スマート」ではなく、SQL Server、Postgres、またはOracleのように最適化されたプランを自動的に作成することと関係があります。ここで最適化するためにできることの1つは、価格列が数値であり、モデル列が各テーブルでインデックス付けされていることを確認することです。

トピックから外れていますが、mysqlを使用しているグーグルについて聞いたとき、彼らはシステムを最適化するdbagurusのチームを持っています。小規模なショップは、SQL Server Express(無料)またはpostgres(オープンソース)を使用したほうがよいでしょう。

于 2012-04-25T17:23:41.707 に答える
1
SELECT CASE WHEN C1.Price<C2.Price THEN C1.COMPANY ELSE C2.COMPANY END AS company, 
       M.Model, 
       CASE WHEN C1.Price<C2.Price THEN C1.Price-M.Price ELSE C2.Price-M.Price END AS diff
FROM MAINTABLE M, COMPTABLE1 C1, COMPTABLE2 C2
WHERE M.Model=C1.Model AND M.Model=C2.Model
ORDER BY diff ASC
LIMIT 3
于 2012-04-25T17:10:37.550 に答える
0

mysqlで大量の計算を行うことはお勧めできません。私たちのプロジェクトでは、ゲームのmysql部分を最適化するのに非常に苦労しています。そして、最良の決定は、phpコードで次にmysqlでハード数学を計算することでした。だからあなたの場所で私はそれをphpでコーディングし、単純なクエリといくつかの結合にのみmysqlを使用したいと思います。

于 2012-04-25T16:58:36.373 に答える