【问题标题】:T-SQL Conditional 'WHERE' Clause and 'IN' Clause to include all the keys in the result setT-SQL 条件“WHERE”子句和“IN”子句包含结果集中的所有键
【发布时间】:2021-02-21 03:58:06
【问题描述】:

我有两个表:TagHistory,其中Tag 表存储所有TagName 的信息,History 表存储从逆变器接收的实时数据。

现在,我有 14 个不同的站点,我可以从中获取逆变器的实时日期,如下所示。

SELECT DISTINCT TagName
FROM History
WHERE TagName LIKE '%DailykWh'

Output

我正在使用相同的查询来查找Value 列的SUM(),方法是将它们与 TagName 分组

SELECT
    TagName,
    SUM (Value) Monthly
FROM
    History h1
WHERE
    TagName IN (
        SELECT DISTINCT
            h2.TagName
        FROM 
            History h2
        WHERE
            h2.TagName LIKE '%DailykWh'
    ) AND 
    DateTime BETWEEN '2020-11-01 00:00:00' AND '2020-11-08 23:59:59'
GROUP BY
    TagName
ORDER BY
    TagName

但结果只包括第一个 TagName,而不是所有 TagName,如下所示。

Output

如果我对子查询中的所有 TagNames 进行硬编码,那么我将获得来自所有站点的结果。我不想对它们进行硬编码,有没有其他方法可以将所有网站都包含在查询结果中?

我是 T-SQL 的新手,我想也许可以使用其他东西来代替 IN 子句,但我不知道是哪一个。任何帮助将不胜感激,谢谢!

【问题讨论】:

  • TagName 列是什么类型 - char 或 varchar?这可以对 LIKE 运算符产生影响。
  • @Arvo TagName 列是“nvarchar”数据类型。
  • @Sai,您好,您确定所有 Value 字段都包含非空数据吗?
  • 为什么你需要一个包含来自同一个表的值的子查询?这与在 WHERE 子句中使用 h1.TagName LIKE '%DailykWh' 不完全相同吗?但似乎您的日期过滤器匹配的行数很少。运行一些简单的查询以查看在该时间段内是否存在多个标签的任何行。
  • @SMor 您的解决方案对我来说效果很好。我用你提到的 WHERE 子句中的附加条件替换了子查询,并且使用 DateTime 列我能够得到我想要的结果。非常感谢!

标签: sql sql-server where-clause in-clause


【解决方案1】:

你可以试试join

SELECT
    t.TagName,
    SUM (Value) Monthly
FROM
    Tag t left join History h on h.tagname=t.tagname
WHERE t.TagName LIKE '%DailykWh'
group by 
    t.TagName
ORDER BY
    t.TagName

【讨论】:

  • 连接也可能是不必要的。但对我来说,为什么原始查询没有产生预期的结果,而硬编码标签值却产生了预期的结果,这对我来说仍然是个谜。
【解决方案2】:

并非所有标签都在历史记录表中可用。可以left join,这样“缺失”的标签就不会被过滤掉:

select t.tagname, sum(h.value) as monthly
from tag t
left join history h on h.tagname = t.tagname
where t.tagname like '%Dailykwh'
group by t.tagname
order by t.tagname

这将为缺少的标签带来null 中的monthly 值。如果你想改用0,请使用coalesce()

coalesce(sum(h.value), 0) as monthly

【讨论】:

  • Tag 表中缺少标签可能确实是当前的问题。如果History 表中的所有标记值在Tag 表中也可用,我猜它会正常工作。在这种情况下,连接可能是不必要的;查询的所有数据都将在 History 表中可用。
  • @BartHofland:是的。这就是为什么“丢失”标签似乎是唯一有意义的场景,考虑到任务中提供的信息。
  • @Fahmi 和@GMB 的答案都很好,谢谢!现在,如果我想在“WHERE”子句中添加另一个条件,比如基于日期进行过滤,该怎么办? ```
  • @Sai:如果是history 的条件,则放入left joinon 子句。
  • 我在History 表中也有所有Tag 值,抱歉之前没有提供这些信息。
【解决方案3】:

从@SMor 给出的回复中,我尝试了以下查询,它对我有用。

SELECT
    TagName,
    SUM (Value) Monthly
FROM
    History
WHERE
    TagName LIKE '%DailykWh' AND
    DateTime BETWEEN '2020-11-01 00:00:00' AND '2020-11-10 23:59:59'
GROUP BY
    TagName
ORDER BY
    TagName

感谢大家的回复和回答。

【讨论】:

    猜你喜欢
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    • 2014-06-25
    相关资源
    最近更新 更多