避免通过执行多个联接来运行多个查询,这不能间隔数月

时间:2018-10-05 09:59:58

标签: sql ms-access

我真的很喜欢这个SQL。我有两个MS Access数据库表设置,如下所示:

数据

ID
UID
MYNAME

月数据

ID
DATAUID
MONTHVAL
VAL

我不想更改此表结构。我在monthdata表中有几个月和几个月的数据量,这些数据与数据表中的引用相关联。

我试图最终在单个查询和一行中返回三个月的数据,像这样:

UID - MONTHVAL - VAL - MONTHVAL - VAL - MONTHVAL - VAL  

因此,如果我们想获取UID ABC123的最后三个月的数据,我正在尝试运行以下查询:

SELECT data.uid, monthdata.monthval, monthdata.val
FROM data
LEFT JOIN monthdata ON data.UID = monthdata.dataUID AND monthdata.monthval = "01/09/2018"
LEFT JOIN monthdata ON data.UID = monthdata.dataUID AND monthdata.monthval = "01/08/2018"
LEFT JOIN monthdata ON data.UID = monthdata.dataUID AND monthdata.monthval = "01/07/2018"
WHERE UID = 'ABC123'

但是它告诉我这是无效的语法。但是,尽管我进行了谷歌搜索,但仍无法找到方法。我能看到的唯一选择是运行三个单独的查询并将日期放在WHERE中,但在实际示例中,我的时间要长得多。

3 个答案:

答案 0 :(得分:2)

当您多次连接表时(例如与monthval一样),每次都必须使用不同的别名。当然,在这种情况下,更改数据库架构是您应该考虑的事情,无论如何语法错误都来自缺少的别名,请尝试以下操作:

SELECT D.uid, M.monthval, M1.monthval, M2.monthval
FROM ((data AS D
LEFT JOIN monthdata AS M ON D.UID = M.dataUID AND M.monthval = #01/09/2018#)
LEFT JOIN monthdata AS M1 ON D.UID = M1.dataUID AND M1.monthval = #01/08/2018#) 
LEFT JOIN monthdata AS M2 ON D.UID = M2.dataUID AND M2.monthval = #01/07/2018#
WHERE UID = 'ABC123';

在上面的i用户中,三个别名分别构成月份数据(MM1M2)和一个别名数据(D),在选择项中我将{ {1}}和M1,但您可以放入所需的那个。

答案 1 :(得分:1)

尝试使用row_number()在下面的情况下尝试输入

    select uid, 
    max(case when  rn=1 then  monthval end) as month1, 
    max(case when  rn=1 then  val end) as val1,
    max(case when  rn=2 then  monthval end) as month2,
    max(case when  rn=2 then  val end) as val2,
    max(case when  rn=3 then  monthval end) as month3, 
    max(case when  rn=3 then  val end) as val3
    from
    (
      SELECT data.uid, monthdata.monthval, monthdata.val,row_number() over(order by uid) as rn FROM data
      LEFT JOIN monthdata ON data.UID = monthdata.dataUID and monthdata.monthval between '01/07/2018' and '01/09/2018'
WHERE UID = 'ABC123')a
      group by uid

答案 2 :(得分:-1)

您的查询有一些问题。一是缺乏别名。另一个是MS Access需要很多多余的括号来进行连接:

SELECT d.uid, md_20180901.val, md_20180801.val, md_20180701.val
FROM ((data as d LEFT JOIN
       (SELECT md.*
        FROM monthdata md
        WHERE md.monthval = "01/09/2018"
       ) as md_20180901
       ON d.UID = md_20180901.dataUID
      ) LEFT JOIN
      (SELECT md.*
       FROM monthdata md
       WHERE md.monthval = "01/08/2018"
      ) as md_20180801
      ON d.UID = md_20180801.dataUID AND md_20180801.monthval = "01/08/2018"
     ) LEFT JOIN
     (SELECT md.*
      FROM monthdata md
      WHERE md.monthval = "01/07/2018"
     ) as md_20180701
     ON d.UID = md_20180701.dataUID AND md_20180701.monthval = "01/07/2018"
WHERE d.UID = "ABC123";

您也可以使用条件聚合来表达这一点:

SELECT d.uid,
       MAX(IIF(md.monthval = "01/09/2018", val, NULL)) as mv_20180901,
       MAX(IIF(md.monthval = "01/08/2018", val, NULL)) as mv_20180801,
       MAX(IIF(md.monthval = "01/07/2018", val, NULL)) as mv_20180701
FROM data as d LEFT JOIN
     monthdata as md
     ON d.UID = md.dataUID 
WHERE d.UID = "ABC123"
GROUP BY d.UID;