使用列数据过滤 SQL 行
Filtering SQL rows using column data
我正在尝试过滤单个 table 中的行。我的目标是 return 所有在 2021 年 7 月 28 日上午 11 点之前“进入”建筑物但尚未“离开”建筑物的车牌。
这是我编写的代码,当然 return 是当天的所有行。
SELECT *
FROM bakery_security_logs
WHERE day = '28' and
month = '7' and
year = '2021' and
hour < '11'
ORDER BY month, day, year;
下面是这段代码 returns:
解决方案 1 - 分组并比较进入或退出的次数。
可以先按license_plate分组,统计车辆进出大楼的次数。如果大楼在上午11点之前进出,entranceCount
和exitCount
应该是一样的。
但是,如果车辆于 11 月 27 日进入,并于 11 月 28 日离开,则此方法可能无效。
SELECT license_plate
FROM (
SELECT
license_plate,
COUNT(CASE WHEN activity = 'entrance' THEN 1 ELSE NULL END) AS entranceCount,
COUNT(CASE WHEN activity = 'exit' THEN 1 ELSE NULL END) AS exitCount
FROM bakery_security_logs
WHERE day = '28' and
month = '7' and
year = '2021' and
hour < '11'
GROUP BY license_plate
)
WHERE entranceCount > exitCount
-- WHERE entranceCount != exitCount
-- if exitCount > entranceCount, may need to be alerted too
解决方案 2 - 获取最新记录并检查 activity
获取每个license_plate
的最新记录。如果 activity = 'entrance'
,车辆在上午 11 点之前仍在大楼内。
这样效率更高,但语法可能会有所不同,具体取决于您使用的 SQL 服务器。
补充建议
使用DATETIME
记录日期时间,这将有助于过滤和排序数据。
我喜欢这个 (MySQL) "one-liner":
SELECT
license_plate,
max(STR_TO_DATE(CONCAT(year, '-', LPAD(month, 2, '0'), '-', LPAD(day, 2, '0'), ' ', LPAD(hour, 2, '0'), ':', LPAD(minute, 2, '0')), '%Y-%m-%d %H:%i')) date_time,
max(activity) activity
FROM bakery_security_logs
WHERE day = '28' and
month = '7' and
year = '2021' and
hour < '11'
GROUP BY license_plate
HAVING activity = 'entrance'
ORDER BY date_time;
我正在尝试过滤单个 table 中的行。我的目标是 return 所有在 2021 年 7 月 28 日上午 11 点之前“进入”建筑物但尚未“离开”建筑物的车牌。
这是我编写的代码,当然 return 是当天的所有行。
SELECT *
FROM bakery_security_logs
WHERE day = '28' and
month = '7' and
year = '2021' and
hour < '11'
ORDER BY month, day, year;
下面是这段代码 returns:
解决方案 1 - 分组并比较进入或退出的次数。
可以先按license_plate分组,统计车辆进出大楼的次数。如果大楼在上午11点之前进出,entranceCount
和exitCount
应该是一样的。
但是,如果车辆于 11 月 27 日进入,并于 11 月 28 日离开,则此方法可能无效。
SELECT license_plate
FROM (
SELECT
license_plate,
COUNT(CASE WHEN activity = 'entrance' THEN 1 ELSE NULL END) AS entranceCount,
COUNT(CASE WHEN activity = 'exit' THEN 1 ELSE NULL END) AS exitCount
FROM bakery_security_logs
WHERE day = '28' and
month = '7' and
year = '2021' and
hour < '11'
GROUP BY license_plate
)
WHERE entranceCount > exitCount
-- WHERE entranceCount != exitCount
-- if exitCount > entranceCount, may need to be alerted too
解决方案 2 - 获取最新记录并检查 activity
获取每个license_plate
的最新记录。如果 activity = 'entrance'
,车辆在上午 11 点之前仍在大楼内。
这样效率更高,但语法可能会有所不同,具体取决于您使用的 SQL 服务器。
补充建议
使用DATETIME
记录日期时间,这将有助于过滤和排序数据。
我喜欢这个 (MySQL) "one-liner":
SELECT
license_plate,
max(STR_TO_DATE(CONCAT(year, '-', LPAD(month, 2, '0'), '-', LPAD(day, 2, '0'), ' ', LPAD(hour, 2, '0'), ':', LPAD(minute, 2, '0')), '%Y-%m-%d %H:%i')) date_time,
max(activity) activity
FROM bakery_security_logs
WHERE day = '28' and
month = '7' and
year = '2021' and
hour < '11'
GROUP BY license_plate
HAVING activity = 'entrance'
ORDER BY date_time;