За последние 24 часа нас посетили 22876 программистов и 1269 роботов. Сейчас ищут 774 программиста ...

Интересная, не стандартная задача по выбоке значений. Нужна помощь

Тема в разделе "PostgreSQL", создана пользователем mikhail.nikula, 9 июн 2017.

  1. mikhail.nikula

    mikhail.nikula Новичок

    С нами с:
    1 сен 2016
    Сообщения:
    11
    Симпатии:
    0
    Прошу помощи, или в каком направлении смотреть.
    Есть таблица с результатами проверки беременности у животных

    id | femaleId | isSuccessful |
    ---+---------+------------+---------------------
    25 | 5 | t
    26 | 5 | f
    27 | 5 | f
    28 | 3 | f
    29 | 3 | t
    29 | 3 | f

    Необходимо выбрать отрицательные значения(isSuccessful =f) у самок (femaleId) котроые идут подряд
    2 и больше раз, сортировка идет по id . Т.е если у одной самки f 2 раза подряд то это знацение подходит
    В данном случае результат выборки должен выглядить как:

    | femaleId | isSuccessful | countsFailResult |
    ---------+------------+---------------------
    | 5 | f | 2

    Если у тойже самой самки f 4 раза после 2 то выбрать те значения которые повторяються чаще.
    Например

    id | femaleId | isSuccessful
    ---+---------+------------+---------------------
    25 | 5 | t
    26 | 5 | f
    27 | 5 | f
    28 | 3 | f
    29 | 3 | t
    30 | 3 | f
    31 | 5 | f
    32 | 5 | f
    33 | 5 | f
    34| 5 | f

    Получим
    id | femaleId | isSuccessful | countsFailResult |
    ---+---------+------------+---------------------
    25 | 5 | f | 4

    Подскажите возможно ли такое реализовать? Или какие вообще есть мысли. Уже 2 сутки голову ломаю, очень интересно.
    Сейчас беру просто запрос с положительными и отрицательными значениями и обрабатываю на php
    но хотелось не тянуть лишнее, и все через запрос сделать.
    Заранее спасибо! Буду очень признателен за помощь
     
  2. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    - доктор, я когда вот так вот делаю, то мне больно!
    - А вы так не делайте!
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    count() и group by
     
  4. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    я вот тоже так подумал сразу... а когда это прочитал
    теперь даже не знаю можно ли средствами MYSQL такое сделать.. group by все сразу сгруппирует..
     
  5. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    об этом нужно думать когда структура данных проектируется
     
  6. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    можно выбрать тех, кто 2
    потом выбрать тех кто 4
    потом выбрать тех, у кого дата первого или последнего 4 после даты из тех, кто 2

    в принципе это можно сделать в базе, и конечно же это можно сделать и в пхп

    но можно действительно изначально думать про такие морочки и придумать какие-то хитрости со структурой, чтобы проще считалось.
    навскидку можно в другую таблицу при отрицательном результате добавлять запись где будет число 0, а при положительном +1 к последней. Тогда можно будет легко выбирать у кого подряд сколько.
     
  7. mikhail.nikula

    mikhail.nikula Новичок

    С нами с:
    1 сен 2016
    Сообщения:
    11
    Симпатии:
    0
    Ну я тоже конечно так пробывал, но как выбрать 2 подряд, а потом 4 подряд?
    Я знаю что в postgres да и вообще в базах данных нет такого понятия как следующая запись, и если мы сгрупируем то сгрупируеться все записи, и те что не рядом.

    единственное что на уме это пронумеровать а потом как то сравнивать типо если номер следующей записи и id животного и рез отрицательный совпадают то запись подходит, если нет то нет и выбрать
    примерно
    Код (Text):
    1.  
    2. WITH SearchPregnancyCheck (INTEGER) AS (
    3.     SELECT
    4.         CAST (
    5.             "animals"."id" AS INTEGER
    6.         ),
    7.         "animals"."femaleId",
    8.         "AnimalsPregnancyCheckData"."isSuccessful"
    9.     FROM
    10.         "AnimalJournal"
    11.     INNER JOIN "AnimalsPregnancyCheckData" ON "AnimalsPregnancyCheckData"."animalId" = "Animal"."id"
    12.     WHERE
    13.         "Animal"."organizationId" = 1
    14.     AND (
    15.         "Animal"."statusId" = 10
    16.         OR "Animal"."statusId" = 15
    17.     )
    18. ),
    19. GroupAnimalPregnancyCheck AS (
    20.     SELECT
    21.         *, ROW_NUMBER () OVER (ORDER BY INTEGER) AS "num",
    22.         1 + ROW_NUMBER () OVER (ORDER BY INTEGER) AS "nextNum"
    23.     FROM
    24.         SearchAnimalPregnancyCheck
    25. )
    26.  
    27.  
    28. SELECT
    29.     *
    30. FROM
    31.     SearchPregnancyCheck
    но естественно составить запрос не получаеться, ли бо рекурсийе
    Код (Text):
    1. WITH RECURSIVE SearchAnimalPregnancyCheck (x) AS (
    2.     SELECT
    3.         CAST (
    4.             "Animal"."id" AS INTEGER
    5.         ),
    6.         "Animal"."femaleId",
    7.         "AnimalPregnancyCheckData"."isSuccessful"
    8.     FROM
    9.         "Animal"
    10.     INNER JOIN "AnimalPregnancyCheckData" ON "AnimalPregnancyCheckData"."journalId" = "Animal"."id"
    11.     WHERE
    12.         "Animal"."organizationId" = 1
    13.     AND (
    14.         "Animal"."statusId" = 10
    15.         OR "Animal"."statusId" = 15
    16.     )
    17. UNION ALL
    18.  
    19. SELECT
    20.     *
    21. FROM
    22.     SearchAnimalPregnancyCheck
    23. )
    24.  
    25. SELECT
    26.     *
    27. FROM
    28.     SearchAnimalPregnancyCheck
    тоже примерно, и там выбирать, но не выходит, вот и интересно мне терпения не хватает или это вообще не выполнимо теми методами которые я пробую, тупо order by и groub by c having тут не подойдут, потому что подряд нужны записи.
     
  8. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    Пересчитывайте в отдельную агрегрирщую таблицу данные по триггеру добавления записи в текущую и не мучайтесь. Столько времени на решение одной задачи на структуре для нее не предназначенной тратить преступно
     
  9. mikhail.nikula

    mikhail.nikula Новичок

    С нами с:
    1 сен 2016
    Сообщения:
    11
    Симпатии:
    0
    Так мне выборку сделать надо а тригеры - Триггеры срабатывают при выполнении с таблицей команды SQL INSERT, UPDATEили DELETE.

    т.е. как я понял перебераю записи если запись подходит то записываю в агрегрирщую таблицу, только как я пойму, что запись подходит и что они идут по пярядку, и что следующая запись мне подходит?
     
  10. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    пишешь следующую строку, если последняя строка соответствует твоим фильтрам для записываемой строки, то увеличиваешь счетчик в агрегаторе по этим же фильтрам ("значения подряд" или что у вас там).