mysql SQL查询,以提取与前一天获取的不正确数据的数据差异

93ze6v8z  于 2023-06-28  发布在  Mysql
关注(0)|答案(3)|浏览(107)

有一个医院数据库,其admissions表的模式如下:

patient_id  INT
admission_date  DATE
discharge_date  DATE
diagnosis   TEXT
room_id         INT
doctor_id   INT
insurance_id    INT

以下是我试图查询的内容:

  • 获取每天的入场总金额。
  • 获取从前一日期更改的录取量。

我尝试了以下查询:

SELECT
 admission_date,
 count(admission_date) as adm_day,
 count(admission_date) - count(admission_date - 1) AS admn_count_change // this count is not correct
FROM admissions
 group by admission_date

**查询结果:**前两列的数据显示正确,最后一列显示不正确的数据,即所有行的值为0,这完全超出了我的理解范围。我不太会用SQL,请多多指教。

r8uurelv

r8uurelv1#

尝试以下查询

SELECT admission_date, count(admission_date) as adm_day,
 count(admission_date) - LAG(count(admission_date)) OVER(ORDER BY admission_date) AS admission_count_change 
FROM admissions
 group by admission_date

LAG()是SQL中的一个窗口函数,它提供对当前行之前的指定偏移值处的行的访问。这意味着在LAG()函数的帮助下,我们可以访问当前行上任何先前行的数据。
更多了解请参考这里:mysql window functionSQLshack

eqqqjvef

eqqqjvef2#

您可以使用

  • GROUP BY获取每天的计数
  • LAG窗口函数获取前一行的值

代码(Oracle语法):

with tmp_dat(pk, admission_date) as (
  select 1, date '2018-06-06' from dual union all
  select 2, date '2018-06-06' from dual union all
  select 3, date '2018-06-07' from dual union all
  select 4, date '2018-06-08' from dual
),
tmp_aggr as (
  SELECT
    admission_date,
    count(admission_date) as adm_day
  from tmp_dat
  group by admission_date
)
select a.*, 
       lag(adm_day) over (partition by 1 order by admission_date) as prev_adm_day,
       adm_day - lag(adm_day) over (partition by 1 order by admission_date) as adm_day_change
 from tmp_aggr a
 order by admission_date;
knpiaxh1

knpiaxh13#

就我个人而言,我更喜欢在应用程序端(或者使用查询结果的任何地方)处理计算,因为我不喜欢引用另一行本身的查询。
但是一个可能的解决方案是使用子选择,其中日期用于连接。
由于没有标记DBMS,因此我使用PostgreSQL 15。除了连接的日期计算外,它应该可以用于大多数DBMS。

SELECT 
   admissions.admission_date, 
   count(admissions.admission_date), 
   count(admissions.admission_date)-calc.prevday as "admission_count_change" FROM admissions
LEFT JOIN (
    SELECT 
       admission_date, 
       count(admission_date) as "prevday" 
    FROM admissions
    GROUP BY admission_date
) as calc ON admissions.admission_date = ( calc.admission_date - interval '1 day')
GROUP BY admissions.admission_date, calc.prevday;

左连接是必要的,这样最新的日期仍然会出现(admission_count_change null)。
我希望这个查询在大表中的伸缩性不是很好。
db<>fiddle to try it out yourself

相关问题