За последние 24 часа нас посетили 20925 программистов и 1129 роботов. Сейчас ищут 382 программиста ...

SQL выборка дубли связной таблицы

Тема в разделе "MySQL", создана пользователем Evgenij85, 4 окт 2018.

Метки:
  1. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    помогите исправить выборку которая считает сумму заказов с дублями при условии что есть аванс ,
    есть выборка
    SELECT sum(order_cost_sum) as order_cost_sum
    FROM `crm_orders`
    LEFT JOIN crm_orders_prepay ON prepay_order_id = order_id
    WHERE order_add_date between '2018-10-02 00:00:00' and '2018-10-02 23:59:59'
    AND order_city =7
    AND prepay_id is not null

    к примеру таблица заказов
    order_id order_cost_sum
    1 100
    2 150
    3 200

    таблица авансов
    prepay_id prepay_order_id prepay_summ
    1 1 50
    2 1 20
    3 2 40

    я ожидаю результат из примера 250
    но мне дает 350 (100+100+150) так как дублирует заказ изза таблицы авансов , подскажите как исправить ?
     
  2. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    не совсем понятно, что дублирует и как оно не должно дублировать, но попробуйте RIGHT вместо LEFT
     
  3. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    ну это так пальцем в небо ..

    дублирует записи с таблицы заказов из за таблицы авансов
     
  4. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Evgenij85, сорь не рассмотрел структуру второй таблицы, позже напишу запрос. Как вариант навскидку вместо таблицы с авансами используйте вложенный запрос.
     
  5. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    та разные использовал варианты но пока что никак
     
  6. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Evgenij85, сделайте пожалуйста SQL дампы таблиц, абсолютно нет времени рисовать их руками. И еще смущает SUM без GROUP BY
    еще раз пальцем в небо, а вдруг прокатит))

    SELECT sum(order_cost_sum) as order_cost_sum
    FROM `crm_orders`
    RIGHT JOIN crm_orders_prepay ON prepay_order_id = order_id
    WHERE order_add_date between '2018-10-02 00:00:00' and '2018-10-02 23:59:59'
    AND order_city =7
    AND prepay_id is not null
    GROUP BY prepay_order_id
     
  7. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    при таком запросе мне отдает следующее
    order_cost_sum
    100
    150

    то есть не группирует а разбивает
     
  8. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    GROUP BY order_cost_sum, prepay_order_id
    и верните наверное LEFT
     
    #8 Valick, 4 окт 2018
    Последнее редактирование: 4 окт 2018
  9. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.734
    Симпатии:
    1.315
    Адрес:
    Лень
    Пример вывода дубляжа:
    PHP:
    1. SELECT * FROM users WHERE login IN
    2. (SELECT login FROM users
    3. GROUP BY login HAVING COUNT(login)>1)
     
  10. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    --- Добавлено ---
    тоже нет
    спасибо я нашел где дублируются, я не могу убрать эти дубли
     
  11. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @MouseZver, вывод дублежа ТС не нужен, да и внешний запрос лишний
    SELECT * FROM users
    GROUP BY login HAVING COUNT(login)>1
    сразу вернёт дубли

    хм... написал и сам засомневался... старость она такая)
     
  12. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    ну это не имеет значения все равно выводит списокм сумм
     
  13. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Evgenij85, да чтож с вам делать-то))) давайте всётаки дампы таблиц, а то у меня пальцев много я долго могу внебо тыкать))
    --- Добавлено ---
    @MouseZver, виноват, поспешил, там конфликт полей будет жеж при * , так что да нужен внешний запрос, хотя я предпочитаю JOIN взамест IN
     
  14. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    SELECT sum(order_cost_sum) as order_cost_sum
    FROM `crm_orders`
    where order_city =7
    and order_add_date between '2018-10-02 00:00:00' and '2018-10-02 23:59:59'
    and order_id NOT IN (
    SELECT order_id
    FROM `crm_orders`
    LEFT JOIN crm_orders_prepay ON prepay_order_id = order_id
    WHERE order_add_date between '2018-10-02 00:00:00' and '2018-10-02 23:59:59'
    AND prepay_id is not null
    GROUP BY order_id HAVING COUNT(order_id)> 1

    )

    при таком варианте удаляет дубли вместе с нормальным ID то есть дублированный ID вообще не учитывается
     
  15. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @Evgenij85, либо обратите внимание на exists, либо обрамите запрос из сообщения №6 ещё одним select для получения общей суммы.
    И можно оставить только join (не left и не right) с таблицей авансов и убрать сравнение "AND prepay_id is not null" за ненадобностью.
     
  16. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    да согласен с JOIN тоже можно но все равно выводится не общая сумма а список сумм
    к примеру
    order_cost_sum
    100
    150
     
  17. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Перечитайте ещё раз внимательно :)
    1. С join нужно без left и без right.
    2. Проверку существования соответствующей записи в другой таблице можно выполнить без join, но с использованием соотнесенного подзапроса в выражении EXISTS (where exists (select 1 from other_table where...))
    3. select sum(order_cost_sum) as order_cost_sum from (select.. тут запрос из №6, с учетом пункта 1...);
    --- Добавлено ---
    В п.3 возможно надо будет псевдоним для подзапроса сообразить :)
     
  18. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    какие именно строки должны сложиться для получения такого результата?
     
  19. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    @Valick, очевидно, ведь, что те, которые получаются в результате твоего запроса из сообщения #6.
    ТС ведь в #7 подтвердил, что числа правильные, не хватает только суммы :)
     
  20. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    не, всё не так просто как хотелось бы :)
     
  21. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.591
    Симпатии:
    360
    Да! Всё ещё проще.
    Однако... нужна сумма всех заказов, имеющим аванс. Всё.
    --- Добавлено ---
    Ну и пара условий по городу и дате размещения заказа (не аванса).
     
  22. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    тьфу блин :(
    Код (Text):
    1. SELECT sum(order_cost_sum) as order_cost_sum FROM
    2. (SELECT DISTINCT prepay_order_id as order_id FROM `crm_orders_prepay` ) poi
    3. LEFT JOIN `crm_orders` USING (order_id)
    это как раз то о чём я говорил в посте №4, но потом почему-то забил себе голову, что надо суммы по авансам раскладывать

    P.S. я 17 раз просил у ТС дампы таблиц, терь пусть WHERE лепит сам куда хочет :D
     
    #22 Valick, 4 окт 2018
    Последнее редактирование: 4 окт 2018
  23. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    Решение



    select sum(order_cost_sum)as order_cost_sum
    from#crm_orders
    where order_add_date between '2018-10-02 00:00:00'and'2018-10-02 23:59:59'
    and order_city =7
    and exists (
    select prepay_order_id
    from#crm_orders_prepay
    where prepay_order_id =#crm_orders.order_id
    )
    ;

    есть еще одно решение

    select sum(order_cost_sum)as order_cost_sum
    from#crm_orders
    where order_add_date between '2018-10-02 00:00:00'and'2018-10-02 23:59:59'
    and order_city =7
    and order_id in(
    select prepay_order_id
    from#crm_orders_prepay
    )
    ;