Как использовать группировку по XXX и правильно использовать агрегатную функцию? С минимальными значениями - PullRequest
1 голос
/ 09 мая 2019

Я пытаюсь получить записи из 4 таблиц с помощью объединений.Эти таблицы тарифы, перевозчики, склады и маржи.Я могу получить нужные записи из этой 4 таблицы, но когда я использую функцию группировки и агрегирования (MIN), мой столбец минимальных продаж корректен, однако другие данные, такие как carrierID, depotID и rateID, отличаются,

У меня есть OriginType (OT) и DestinatioType (DT), и для каждого есть 2 случая;Депо и Дверь.Поэтому, когда я группирую их, я получаю четыре варианта (услуги):

  • Депо в депо
  • Депо до двери
  • Дверь в депо
  • От двери до двери

Я пытаюсь получить минимальные (ставки) как «Sell» для каждого из этих сервисов и отобразить их.Продажа рассчитывается следующим образом:

  1. таблица autoRate, так как A имеет столбец Buy, перевозчик, OT, DT, Origin ( значение: Канберра ), пункт назначения ( значение:Мельбурн ) и Автомобиль ( Значение: 4WD / Van )
  2. Left Соединяется с носителями как C с A.carrier = C.ID
  3. C.Fuellevy столбец как Процент ((C.FuelLevy * A.buy) + C.FuelLevy) как EQ1
  4. ((EQ1 * 10%) + EQ1) как EQ2
  5. Цена EQ2 для каждой строки с таблицей маржи в процентах.Например, если значение EQ2 равно 400, то оно будет выглядеть в таблице «Маржа», найти диапазон (низкий и высокий, например, 350 (низкий) и 500 (высокий)), и его процент будет равен 25%, поэтому ((EQ2 * 25%)+ EQ2) даетпродать значение.

Я не слишком уверен, как загрузить сюда свои данные и таблицу базы данных, поэтому я попытался объяснить здесь, что я хочу.

запрос, который я строюэто: -

Select   Depo.*,  DL.id as DepoID,  DL.carrier as CarNo, DL.depotCity, DL.depoSuburb, min(Depo.Sell)  as sellcost , Depo.OriginType as OT From (
    Select Mar.*,  M.MarginPer, round((eq2 * M.MarginPer) + eq2)as Sell   From (
                        Select GST.* , EQ1 as 'FinalEQ1' , round((EQ1 * .10) + EQ1,2) as eq2 From (
                                Select A.ID as RateID, A.Origin, A.OriginState, A.Destination, A.DestinationState, A.Carrier as RateCarrier, A.Car as CarType, A.Buy as Buy, A.OriginType, A.DestinationType ,
                                C.ID as CarrierID, C.Carrier, C.FuelLevy , round((A.buy * C.FuelLevy) + A.Buy, 2) As EQ1,
                                CONCAT(A.OriginType, ' to ' ,A.DestinationType ) as service,
                                 D.id as DepoID,  D.carrier as CarNo, D.depotCity, D.depoSuburb
                                from carrier C
                                left join autorates A on A.carrier = C.ID
                                left join dList D on D.carrier =  C.ID
                                where A.origin = 'Canberra' and A.destination = 'Melbourne' and A.car = '4WD/Van'  AND  D.carrier = A.carrier AND A.goodsAllowed =  0
                                AND C.Disabled = 0
                                AND D.depotCity  = 'Canberra'
                                 order by  EQ1
                            ) As GST
                        order by  eq2
             ) As Mar
             Left Join margin M on Mar.eq2 >=  M.low and  Mar.eq2 <= M.high
                   order by  Sell
        ) As Depo
            Left  Join dList DL  on DL.Carrier = Depo.RateCarrier
            Where DL.depotCity = 'Melbourne'
             group by OT
             order by  sellcost

Результаты перед Группой и MIN (): - enter image description here

Как мы видим, стоимость продажи 412 иЗдесь carNo равен 51

enter image description here

И на этом снимке экрана номер оператора изменился, но значение MIN осталось прежним.

Ответы [ 2 ]

1 голос
/ 09 мая 2019

Я только что справился с запросом get.Это будет работать, как я проверил на моем SQL-WB

SELECT DepoD.*, DL2.id, DL2.carrier AS a, DL2.depotCity
    , DL2.depoSuburb AS 'PickupSub', MIN(Sell) AS sellcost 
FROM ( 
    SELECT Depo.*, DL.id AS DepoID, DL.carrier AS CarNo, DL.depotCity, DL.depoSuburb AS 'PickupSub'
        , DL.depoSuburb AS 'DestSub', MIN(Sell) AS sellcost, Depo.OriginType AS OT 
    FROM (
        SELECT Mar.*, M.MarginPer, MIN(round((eq2 * M.MarginPer) + eq2)) AS Sell 
        FROM (
            SELECT GST.*, EQ1 AS 'FinalEQ1', MIN(round((EQ1 * .10) + EQ1, 2)) AS eq2 
            FROM (
                SELECT A.ID AS RateID, A.Origin, A.OriginState, A.Destination, A.DestinationState
                    , A.Carrier AS RateCarrier, A.Car AS CarType, A.Buy AS Buy,  A.OriginType
                    , A.DestinationType, C.ID AS CarrierID, C.Carrier, C.FuelLevy
                    , round((A.buy * C.FuelLevy) + A.Buy, 2) AS EQ1
                    , CONCAT(A.OriginType, ' to ', A.DestinationType ) AS service 
                FROM carrier C
                LEFT JOIN autorates A ON A.carrier = C.ID
                WHERE A.origin = 'Melbourne' 
                    AND A.destination = 'Canberra' 
                    AND A.car = '4WD/Van' 
                    AND A.goodsAllowed = 0
                    AND C.Disabled = 0
                ORDER BY EQ1 ASC
            ) AS GST
            GROUP BY service, CarrierID
            ORDER BY eq2
        ) AS Mar
        LEFT JOIN margin M ON Mar.eq2 >= M.low AND Mar.eq2 <= M.high
        GROUP BY service
        ORDER BY Sell
    ) AS Depo
    LEFT JOIN dList AS DL ON DL.Carrier = Depo.RateCarrier
    WHERE DL.depotCity IN('Melbourne', 'Canberra') 
    GROUP BY carrier, service
    ORDER BY sellcost
) AS DepoD
LEFT JOIN dList DL2 ON DL2.Carrier = DepoD.RateCarrier
WHERE DL2.depotCity IN('Melbourne', 'Canberra') 
GROUP BY carrier, service
ORDER BY sellcost
0 голосов
/ 09 мая 2019

ПРИМЕЧАНИЕ: Не окончательный ответ, а запрос для проверки и проверки работоспособности этой части. Если так, я предоставлю остальную часть запроса.


Если вы решите проблему, я думаю, что вам нужно определить наименьшую продажу для каждой комбинации OriginType и DestinationType. Затем присоединитесь к таблицам, чтобы получить соответствующие строки.

Запрос ниже не получает всю подробную информацию, но он должен получить строки с наименьшим значением Sell. Если это работает, то я могу добавить к запросу, чтобы получить другие, соответствующие данные.

Одним аспектом этого вопроса является использование LEFT JOIN. Это может включать строки, которые не соответствуют предложениям ON, по существу добавляя столбцы с нулевыми значениями. Это может повлиять на производительность, и использование JOIN может работать лучше. Если вы проверите это, и оно работает, как указано ниже, запустите его снова без LEFT, который находится перед каждым из предложений JOIN. Если вы получите те же результаты, дайте мне знать в комментариях.

Попробуйте и посмотрите, получите ли вы четыре значения для каждой из комбинаций OriginType и DestinationType. Если это произойдет, я обновлю ответ остальной частью запроса.

SELECT
    A.OriginType,
    A.DestinationType,
    round(A.buy * (1.0 + C.FuelLevy), 2) AS EQ1,
    round(round(A.buy * (1.0 + C.FuelLevy), 2) * 1.10, 2) AS eq2,
    MIN(round((eq2 * (1.0 + M.MarginPer)))) AS Sell
FROM carrier C
LEFT JOIN autorates A
    ON A.carrier = C.ID
LEFT JOIN dList D
    ON D.carrier = A.carrier
LEFT JOIN margin M
    ON round(round(A.buy * (1.0 + C.FuelLevy), 2) * 1.10, 2) BETWEEN M.low AND M.high
WHERE A.origin = 'Canberra'
    AND A.destination = 'Melbourne'
    AND A.car = '4WD/Van'
    AND A.goodsAllowed =  0
    AND C.Disabled = 0
    AND D.depotCity  = 'Canberra'
GROUP BY LOWER(A.OriginType), LOWER(A.DestinationType)
ORDER BY Sell
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...