MYSQL-控制流功能

时间:2013-02-14 19:10:15

标签: mysql

现在已经工作了几个小时,我想知道在SQL中是否有推荐的解决方案,或者我最好把它放在我的应用程序逻辑而不是数据库中。我更喜欢前者。

CREATE TABLE `rate_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`city` varchar(100) DEFAULT NULL,
`rate_type` varchar(45) DEFAULT NULL,
`rate` int(11) DEFAULT NULL,
`vendor` varchar(45) DEFAULT NULL,
`product` varchar(45) DEFAULT NULL,
`days_to_pickup` int(11) DEFAULT NULL,
`timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`state` varchar(45) DEFAULT NULL,
`country` varchar(45) DEFAULT NULL,
 PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=787 DEFAULT CHARSET=latin1$$

鉴于城市,州和城市,我需要对每种产品和供应商组合的平均费率进行最佳估算。国家。每个供应商可以拥有不同数量的产品。此外,每个城市的供应商数量可能不同。逻辑需要

  1. 如果找到匹配项,则返回与城市,州和国家/地区匹配的记录的数据。
  2. 如果找不到匹配项,请尝试根据州和州找到结果。国家。
  3. 如果这也没有返回任何内容,请仅根据国家/地区查找结果
  4. 最后,使用所有记录来计算每种产品,供应商组合的平均费率
  5. 其他列还有其他逻辑,但它们都遵循与位置相同的模式。
  6. 第一个查询将类似于

    select avg(rate) rate, vendor, product from rate_info
    where city = 'Boston'
    and state = 'MA'
    and country = 'United States'
    and rate_type = 'REGULAR'
    and days_to_pickup >= 4
    group by vendor, product 
    

    我一直在玩COALESCE,CASE,IFNULL,但无法让查询工作。我可以在应用程序层中执行此操作,但是我必须对数据库进行多次调用,因为很可能不会遇到第一种情况。

    理想的解决方案就像是

    COALESCE(select_city_state_cntr, select_state_cntry, select_cntry);
    

    如果遗漏了某些内容,请告诉我,我会根据需要添加更多详细信息。

    谢谢

3 个答案:

答案 0 :(得分:1)

这是一个可能的解决方案。查询所有三种方式,并使用LIMIT取第一个匹配的方式。

SELECT * FROM (
 (SELECT SUM(population) AS population, city, state, country
  FROM POPULATION
  WHERE (city, state, country) = (?, ?, ?))
 UNION ALL
 (SELECT SUM(population), NULL, state, country
  FROM POPULATION
  WHERE (state, country) = (?, ?))
 UNION ALL
 (SELECT SUM(population), NULL, NULL, country
  FROM POPULATION
  WHERE (country) = (?))) AS t
WHERE t.population IS NOT NULL
LIMIT 1;

答案 1 :(得分:0)

一种方法是:

CREATE TABLE `population` (
  `city` varchar(64) NOT NULL,
  `state` varchar(64) NOT NULL,
  `country` varchar(64) NOT NULL,
  `population` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

和一个选择查询:

SELECT city, state, country, population
  FROM population
 WHERE country = '<country>' AND state = '<state>' AND city = '<city>'
UNION
SELECT null, state, country, sum(population)
  FROM population
 WHERE country = '<country>' AND state = '<state>'
 GROUP BY state
UNION
SELECT null, null, country, sum(population)
  FROM population
 WHERE country = '<country>'
 LIMIT 1;

答案 2 :(得分:0)

这应该给你正确的结果(如果我的要求是正确的),虽然它没有效率,因为它计算所有选项,即使在找到exect城市的情况下:

SELECT 
  (city = 'Boston') * rate AS exactCityData, 
  SUM((city != 'Boston' AND state = 'MA') * rate) AS wholeStateData, 
  SUM((city != 'Boston' AND state != 'MA' AND country = 'United States') * rate) AS wholeCountryData
WHERE country = 'United States'
GROUP BY vendor, product;

对于州平均值,您不能使用AVG,因为查询匹配所有行(在国家/地区),因此查询应该是这样的:

SELECT 
  (city = 'Boston') * rate AS exactCityData, 
  SUM((state = 'MA') * rate) / SUM(state = 'MA') AS wholeStateData, 
  AVG(rate) AS wholeCountryData
WHERE country = 'United States'
GROUP BY vendor, product;

现在用于“最后的手段”选项,删除国家/地区要求,并将AVG(rate) AS wholeCountryData部分替换为SUM((country = 'United States') * rate) / SUM(country = 'United States') AS wholeCountryData