我的SQL查询,根据表中其他列的值来获取范围间隔内的值


My SQL query to get the values coming in a range intervals depending on the value of other column of the table

嗨,我使用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和有同样的价格所以我将使用这些分组和共同value756, 7583, 7584, 7585, 7586这是在7580 - 7589,但有两个值范围的价格,所以我们不能使用集团全系列的代码将作为它的。我需要修剪只有当代码之间的范围10和有相同的价格。

让我明确我的要求,我有国家名称,国家代码,城市代码和价格的数据库,我从excel读取值。在国家字段中,excel行中只有一个值,如225或2247或226,而在城市代码中,将有对应于国家的值,如120,123-129, 165-169可能是1-5等。

通常情况下,我的要求是连接国家代码和相应的城市代码,如225,如果城市代码列包含120,123-129, 165-169,那么值将是225120,225123,225124,225125,225126,225127,225128,225129,225165,225166,225167,225168,225169这是我最初的数据库场景。但是如果国家代码是225,城市代码是空白的,226是另一个国家代码,城市代码是空白的,因为对于正确的国家代码,城市代码将是空白的。因此,适当的国家代码值不会被修剪,它们将被视为225,226,即使它们具有相同的价格。只有在连接城市代码的情况下,这些值才会被修剪。

是否有最好的方法来做这个MySQL查询

谢谢

我不认为有一种方法可以用索引友好的方式编写这个查询,所以如果它一直运行,你可能想要重构你的数据。

查询将代码削减到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

我想我明白你想做什么。下面是一个非常低效的查询,旨在逐步了解如何在查询中执行此操作。如果它像你想要的那样工作,你可以优化它:

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;