SQL - COUNT () не работает должным образом - PullRequest
0 голосов
/ 18 мая 2019

Я присоединился к нескольким таблицам и отфильтровал результаты, используя следующий код.

SELECT jmeno, prijmeni, adresa, vozidlo.spz, snimek.timestamp
FROM majitel
INNER JOIN vozidlo ON majitel.id_majitel = vozidlo.id_majitel
INNER JOIN kat_kamera ON kat_kamera.id_kategorie = vozidlo.id_kategorie
INNER JOIN snimek ON kat_kamera.id_kamera = snimek.id_kamera
WHERE TIMESTAMP >= TIMESTAMP(NOW() - INTERVAL 2 DAY)

Вот результат.

jmeno   prijmeni    adresa  spz         timestamp
John    Doe         Prague  7A2 5109    17/05/2019 08:21
John    Doe         Prague  7A2 5109    17/05/2019 20:50
Vanessa Green       Pilsen  4P8 9370    17/05/2019 06:14
John    Doe         Prague  7A2 5109    17/05/2019 20:50
Vanessa Green       Pilsen  4P8 9370    17/05/2019 12:27
Vanessa Green       Pilsen  4P8 9370    17/05/2019 14:31
John    Doe         Prague  7A2 5109    18/05/2019 15:35

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

Поэтому я изменил запрос следующим образом.

SELECT jmeno, prijmeni, adresa, vozidlo.spz, snimek.timestamp
FROM majitel
INNER JOIN vozidlo ON majitel.id_majitel = vozidlo.id_majitel
INNER JOIN kat_kamera ON kat_kamera.id_kategorie = vozidlo.id_kategorie
INNER JOIN snimek ON kat_kamera.id_kamera = snimek.id_kamera
WHERE TIMESTAMP >= TIMESTAMP(NOW() - INTERVAL 2 DAY)
HAVING COUNT(jmeno) >= 3

Но, к сожалению, это не работает. Поскольку это только возвращает это.

jmeno   prijmeni    adresa  spz         timestamp
John    Doe         Prague  7A2 5109    17/05/2019 08:21

Но в конечном результате должны быть и Джон Доу , а также Ванесса Грин .

Не могли бы вы помочь мне получить желаемый результат?

Ответы [ 3 ]

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

Вам нужен GROUP BY.MySQL допускает предложение HAVING без GROUP BY.Весь запрос считается запросом агрегации и возвращает ровно одну строку.

Если вам нужны только повторяющиеся части:

SELECT jmeno, prijmeni, adresa, v.spz
FROM majitel m INNER JOIN
     vozidlo v
     ON m.id_majitel = v.id_majitel INNER JOIN
     kat_kamera kk
     ON kk.id_kategorie = v.id_kategorie INNER JOIN
     snimek s
     ON kk.id_kamera = s.id_kamera
WHERE TIMESTAMP >= TIMESTAMP(NOW() - INTERVAL 2 DAY)
GROUP BY jmeno, prijmeni, adresa, v.spz
HAVING COUNT(*) >= 3;

(я рекомендую вам указать все имена столбцов, так что понятно, из каких таблиц они происходят.)

* timestamp сложнее включить.Возможно, будет достаточно объединить их в одну строку:

SELECT jmeno, prijmeni, adresa, v.spz,
       GROUP_CONCAT(timestamp) as timestamps
FROM majitel m INNER JOIN
     vozidlo v
     ON m.id_majitel = v.id_majitel INNER JOIN
     kat_kamera kk
     ON kk.id_kategorie = v.id_kategorie INNER JOIN
     snimek s
     ON kk.id_kamera = s.id_kamera
WHERE TIMESTAMP >= TIMESTAMP(NOW() - INTERVAL 2 DAY)
GROUP BY jmeno, prijmeni, adresa, v.spz
HAVING COUNT(*) >= 3;

Если вы хотите отдельные строки, то в MySQL 8+ вы можете использовать оконные функции:

SELECT x.*
FROM (SELECT jmeno, prijmeni, adresa, v.spz, timestamp,
             COUNT(*) OVER (jmeno, prijmeni, adresa, v.spz) as cnt
      FROM majitel m INNER JOIN
           vozidlo v
           ON m.id_majitel = v.id_majitel INNER JOIN
           kat_kamera kk
           ON kk.id_kategorie = v.id_kategorie INNER JOIN
           snimek s
           ON kk.id_kamera = s.id_kamera
      WHERE TIMESTAMP >= TIMESTAMP(NOW() - INTERVAL 2 DAY)
      GROUP BY jmeno, prijmeni, adresa, v.spz
     ) x
WHERE cnt >= 3;
0 голосов
/ 18 мая 2019

Это можно сделать, используя ROW_NUMBER и EXISTS, если вы не хотите потерять информацию о каждой отметке времени.Попробуйте это:

WITH CTE AS
(
    SELECT 
         jmeno
        ,prijmeni
        ,adresa
        ,vozidlo.spz
        ,snimek.timestamp
        ,ROW_NUMBER() OVER (PARTITION BY jmeno ORDER BY jmeno) as number
    FROM majitel
    INNER JOIN vozidlo ON majitel.id_majitel = vozidlo.id_majitel
    INNER JOIN kat_kamera ON kat_kamera.id_kategorie = vozidlo.id_kategorie
    INNER JOIN snimek ON kat_kamera.id_kamera = snimek.id_kamera
    WHERE TIMESTAMP >= TIMESTAMP(NOW() - INTERVAL 2 DAY)
)
SELECT
    *
FROM CTE
WHERE exists (
                SELECT 1
                FROM CTE
                where CTE.jmeno = jmeno
                and CTE.number >= 3
              )
0 голосов
/ 18 мая 2019

Вы должны использовать group by и считать (*)

  SELECT jmeno, prijmeni, adresa, vozidlo.spz, min(snimek.timestamp)
  FROM majitel
  INNER JOIN vozidlo ON majitel.id_majitel = vozidlo.id_majitel
  INNER JOIN kat_kamera ON kat_kamera.id_kategorie = vozidlo.id_kategorie
  INNER JOIN snimek ON kat_kamera.id_kamera = snimek.id_kamera
  WHERE TIMESTAMP >= TIMESTAMP(NOW() - INTERVAL 2 DAY)
  group by jmeno, prijmeni, adresa, vozidlo.sp
  HAVING COUNT(*) >= 3

и используйте функцию агрегирования для уменьшения значений меток времени (например, min ())

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...