Задавайте вопросы, мы ответим
Вы не зашли.
Добрый день! Есть таблица(см. рисунок). Скажите, пожалуйста, как правильно сформировать запрос, чтобы для каждого CLAIM_ID правильно выбирался STORAGE_ID?
Запрос SELECT * , MIN( DISTANCE ) FROM `table` GROUP BY `CLAIM_ID` выдаёт неверный результат.
Как видно из рисунка, для каждого CLAIM_ID STORAGE_ID равен 58 - что неверно.
Правильно:
для CLAIM_ID = 1, STORAGE_ID = 43366;
для CLAIM_ID = 1, STORAGE_ID = 35859;
Как написать правильный запрос?
В свою очередь могу поделиться хранимой функцией, которая вычисляет столбец DISTANCE на основании пары геокоординат(улучшенная формула гаверсинусов для антиподов).
Заранее благодарен!
Неактивен
Добрый день!
Не вполне понятно, как именно нужно выбирать STORAGE_ID для каждого CLAIM_ID?
И сколько именно нужно выбрать STORAGE_ID для каждого CLAIM_ID? Один или два или сколько? (А главное, почему один, два, или три).
Товарно-рыночные отношения на форуме sqlinfo в виде обмена хранимками - наверное первый случай в истории форума !
Глянуть, безусловно, интересно на такую хранимку.
А какой Датум? WGS84?
Неактивен
Есть один CLAIM_ID(заявка) и есть сотни STORAGE_ID(склады). Нужно найти ближайший(соответственно, единственный) склад к каждой заявке(в данном случае их две) - вот такая задача.
Вот хранимка
DELIMITER //
CREATE FUNCTION DISTANCE(lat1 DOUBLE, lng1 DOUBLE, lat2 DOUBLE, lng2 DOUBLE)
RETURNS DOUBLE
BEGIN
DECLARE deltaLng, cosLat1, cosLat2, sinLat1, sinLat2, cosDeltaLng, sinDeltaLng, y1, y2, x1, x2, x, y, R DOUBLE;
SET R=6372795;
SET lat1 = lat1*0.017453292519943295769;
SET lng1 = lng1*0.017453292519943295769;
SET lat2 = lat2*0.017453292519943295769;
SET lng2 = lng2*0.017453292519943295769;
SET deltaLng = ABS(lng2-lng1);
SET cosLat1 = COS(lat1);
SET cosLat2 = COS(lat2);
SET sinLat1 = SIN(lat1);
SET sinLat2 = SIN(lat2);
SET cosDeltaLng = COS(deltaLng);
SET sinDeltaLng = SIN(deltaLng);
SET y1 = cosLat2*sinDeltaLng;
SET y2 = cosLat1*sinLat2-sinLat1*cosLat2*cosDeltaLng;
SET y = SQRT(y1*y1+y2*y2);
SET x1 = sinLat1*sinLat2;
SET x2 = cosLat1*cosLat2*cosDeltaLng;
SET x = x1 + x2;
RETURN ATAN2(y,x)*R;
END //
Отредактированно Дмитрий79 (07.08.2016 17:03:16)
Неактивен
CREATE TABLE IF NOT EXISTS `distances_268` (
`CLAIM_ID` int(18) unsigned NOT NULL DEFAULT '0',
`LAT1` double(20,12) DEFAULT '0.000000000000',
`LNG1` double(20,12) DEFAULT '0.000000000000',
`LAT2` double DEFAULT NULL,
`LNG2` double DEFAULT NULL,
`STORAGE_ID` int(11) unsigned NOT NULL DEFAULT '0',
`DISTANCE` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `distances_268` (`CLAIM_ID`, `LAT1`, `LNG1`, `LAT2`, `LNG2`, `STORAGE_ID`, `DISTANCE`) VALUES
(1, 60.976641000000, 32.955478000000, 66.5281, 66.590989, 58, 1739997.10851877),
(1, 60.976641000000, 32.955478000000, 66.60495, 66.615315, 59, 1741792.47486379),
(1, 60.976641000000, 32.955478000000, 66.527108, 66.63816, 60, 1742070.80418416),
(1, 60.976641000000, 32.955478000000, 66.525077, 66.58745, 61, 1739813.14727011),
(1, 60.976641000000, 32.955478000000, 66.530715, 66.613851, 62, 1741030.37968224),
(1, 60.976641000000, 32.955478000000, 66.535019, 66.589067, 63, 1739975.89509031),
(1, 60.976641000000, 32.955478000000, 66.526771, 66.589157, 64, 1739904.03823327),
(1, 60.976641000000, 32.955478000000, 66.530715, 66.613851, 65, 1741030.37968224),
(1, 60.976641000000, 32.955478000000, 66.527108, 66.63816, 66, 1742070.80418416),
(1, 60.976641000000, 32.955478000000, 56.252627, 38.115437, 35859, 604083.105780824),
(1, 60.976641000000, 32.955478000000, 58.307715, 32.490222, 43366, 298002.497726852),
(2, 56.718187000000, 38.828160000000, 66.5281, 66.590989, 58, 1803606.473075),
(2, 56.718187000000, 38.828160000000, 66.60495, 66.615315, 59, 1808046.25611387),
(2, 56.718187000000, 38.828160000000, 66.527108, 66.63816, 60, 1805475.54941968),
(2, 56.718187000000, 38.828160000000, 66.525077, 66.58745, 61, 1803327.58157761),
(2, 56.718187000000, 38.828160000000, 66.530715, 66.613851, 62, 1804650.6583059),
(2, 56.718187000000, 38.828160000000, 66.535019, 66.589067, 63, 1803838.55600679),
(2, 56.718187000000, 38.828160000000, 66.526771, 66.589157, 64, 1803472.66485256),
(2, 56.718187000000, 38.828160000000, 66.530715, 66.613851, 65, 1804650.6583059),
(2, 56.718187000000, 38.828160000000, 66.527108, 66.63816, 66, 1805475.54941968),
(2, 56.718187000000, 38.828160000000, 56.252627, 38.115437, 35859, 67802.7395046658),
(2, 56.718187000000, 38.828160000000, 58.307715, 32.490222, 43366, 417658.344099849)
Неактивен
Большое спасибо за ссылку!
Как видим, значение поля post взято не из той строки, которая соответствует max(`time`). А если результат правильный, то это не более чем случайность. написал:
Василий Лукьянчиков
Как раз мой случай.
Вероятность, что есть 2 ближайших склада для заявки, стремится к нулю, т.к. различие будет, пусть даже и доли миллиметра. В таблице расстояние в метрах.
Получается, что такая тривиальная, казалось бы задача, на поверку оказывается несколько сложной.
Отредактированно Дмитрий79 (07.08.2016 21:53:00)
Неактивен