0

こんにちは、私は PHP と mysql を使用しています。データベース テーブルは次のとおりです。

Code  Price
226   0.001
7565  0.001
7566  0.001
7567  0.001
7568  0.001
7569  0.001
7570  0.001
7571  0.001
7572  0.001
7583  0.002
7584  0.002
7585  0.003
7586  0.003

そして、次のような出力が必要です:

Code  Price
226   0.001
756   0.001
757   0.001
7583  0.002
7584  0.002
7585  0.003
7586  0.003

つまり、価格が10の範囲にある場合、価格が同じ場合は最後の値をトリミングする必要があり、異なる価格が10の範囲にある場合、コードはそのままになります。

上記の 226 には 220 と 229 の間にそれ以上の値がない単一の値があるため、この値を 226 - 0.001 とします。また、7565 から 7569 まで、これらの数値は 7560 から 7569 の範囲にあり、同じ価格であるため、これらにグループ化を使用します共通の値756を取得し、7583、7584、7585、7586の場合、これらは7580〜7589の範囲にありますが、価格の2つの値があるため、コードの全範囲にグループを使用できないため、そのままになります。コードが 10 の範囲内にあり、価格が同じ場合にのみトリミングが必要です。

国名、国コード、都市コード、価格のデータベースがあり、Excel から値を読み取っています。国フィールドには、 225 または 2247 または 226のような Excel の行に 1 つの値しかなく、都市コードには、120、123-129、165-169 などの国に対応する値があります

通常、私の要件は、都市コードの列に120,123-129, 165-169が含まれている場合、国コードと対応する都市コードを225のように連結することでした。 225166,225167,225168,225169 これが私の最初のデータベース シナリオです。しかし、国コードが 225 で都市コードが空白で、226 が別の国コードで都市コードが空白の場合、都市コードは適切な国コードに対して空白になるため、もう 1 つ問題があります。したがって、適切な国コードの値はトリムされず、価格が同じであっても225,226と見なされます。値は、都市コードが連結されている場合にのみトリムされます。

MySQLクエリでこれを行う最善の方法はありますか?

ありがとう

4

2 に答える 2

1

このクエリをインデックスに適した方法で記述する方法はないと思います。そのため、このクエリが常に実行される場合は、代わりにデータを再構築することをお勧めします。

クエリはコードを 3 文字に削減します。226 は短縮されていないため、これは正しいと思います。

SELECT SUBSTR(Code,1,3) Code, Price FROM Test
GROUP BY SUBSTR(Code,1,3) HAVING COUNT(DISTINCT Price) = 1
UNION
SELECT Code, Price FROM Test WHERE SUBSTR(Code, 1, 3) IN
  (SELECT SUBSTR(Code,1,3) Code FROM Test
   GROUP BY SUBSTR(Code,1,3) HAVING COUNT(DISTINCT Price) > 1)

でテストする SQLfiddle

編集:要件を更新した後、国コードが一定の長さ (3) である限り、これは動的な長さで機能すると思います。

SELECT SUBSTR(Code,1,GREATEST(3,LENGTH(Code)-1)) Code, Price FROM Test
GROUP BY SUBSTR(Code,1,GREATEST(3,LENGTH(Code)-1)) 
  HAVING COUNT(DISTINCT Price) = 1
UNION
SELECT Code, Price FROM Test
WHERE SUBSTR(Code, 1, GREATEST(3,LENGTH(Code)-1)) IN
  (SELECT SUBSTR(Code,1,GREATEST(3,LENGTH(Code)-1)) Code FROM Test
   GROUP BY SUBSTR(Code,1,GREATEST(3,LENGTH(Code)-1)) 
     HAVING COUNT(DISTINCT Price) > 1)

別の SQLfiddle

于 2013-03-09T07:38:45.663 に答える
0

私はあなたが何をしようとしているのか理解していると思います。以下は、クエリで実行する方法を順を追って説明するために設計された非常に非効率的なクエリです。希望どおりに動作する場合は、最適化できます。

select distinct code, price
from (
    select case when pricecount>1 then code else code10 end as code,
    price
    from test
    join (
        select code10, count(distinct(price)) as pricecount
        from (
            select floor(code/10) as code10, price
            from test
        ) a group by code10
    ) b
    on floor(test.code/10)=b.code10
) c;
于 2013-03-09T07:09:26.990 に答える