[英]MYSQL- Control Flow Functions
Been working on this for a couple of hours now and I wonder if there is a recommended solution for this in SQL or if I am better off putting this in my application logic instead of the database. 现在已经进行了两个小时的工作,我想知道是否有建议的SQL解决方案,或者最好将其放在应用程序逻辑中而不是数据库中。 I'd prefer the former. 我希望前者。
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$$
I need come up with the best estimate for average rate of each product and vendor combination, given a city, state & country. 考虑到城市,州和国家/地区,我需要针对每种产品和供应商组合的平均费率得出最佳估计。 Each vendor can have a different number of products. 每个供应商可以拥有不同数量的产品。 Also, the number of vendors in each city can be different. 此外,每个城市的供应商数量可能不同。 The logic needs to be 逻辑需要
The first query will be something like 第一个查询将类似于
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
I have been playing around with COALESCE, CASE, IFNULL, but can't get the queries to work. 我一直在玩COALESCE,CASE,IFNULL,但是无法使查询正常工作。 I can do it in the application layer, but I'd have to make multiple calls to the database as there is high likelihood that the first case will not be met. 我可以在应用程序层中完成此操作,但是由于极有可能无法满足第一种情况,因此我必须对数据库进行多次调用。
The ideal solution would be something like 理想的解决方案是
COALESCE(select_city_state_cntr, select_state_cntry, select_cntry);
Let me know if something is missing and I'll add more details as required. 让我知道是否缺少某些东西,我将根据需要添加更多详细信息。
Thank you 谢谢
Here's a possible solution. 这是一个可能的解决方案。 Query all three ways, and use LIMIT to take the first one that matches. 查询所有三种方式,并使用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;
One way would be: 一种方法是:
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;
and a select query: 和选择查询:
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;
This should give you right results (if I got you requirements right), though its not efficient, since it calculates all options even in case exect city is found: 这应该给您正确的结果(如果我满足您的要求),尽管效率不高,因为即使在找到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;
For state average, you cannot use AVG, since query matches all rows (in country), thus the query should be like that: 对于平均状态,您不能使用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;
Now for firth "last resort" option, drop country requirement, and replace AVG(rate) AS wholeCountryData
part with SUM((country = 'United States') * rate) / SUM(country = 'United States') AS wholeCountryData
现在,对于第一个“最后一招”选项,删除国家/地区要求,并用SUM((country = 'United States') * rate) / SUM(country = 'United States') AS wholeCountryData
替换AVG(rate) AS wholeCountryData
部分
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.