如果where子句返回零行,则选择虚拟值

时间:2019-03-26 15:58:27

标签: sql sql-server

我正在使用SQL Server2016。我有一个SQL,它具有where子句,该子句根据特定时间表中存在的数据返回零或非零行。例如,SQL是:

select step_id,
       step_name
  from msdb.dbo.sysjobhistory
 where step_id = 9999

我想要的是当SQL返回零行时,则它应该返回具有我可以指定的伪值的一行。

我尝试过的事情:我可以使用以下SQL来做到这一点:

DECLARE @Condition int 
SET @Condition = 0;
IF (
    SELECT count(*) FROM
    (
     select step_id,
            step_name
       from msdb.dbo.sysjobhistory
       where step_id = 9999
    ) t1
   ) > 0
BEGIN
    SET @Condition = 1;
END;

IF @Condition = 1
BEGIN
select step_id,
       step_name
  from msdb.dbo.sysjobhistory
 where step_id = 9999
END
ELSE
BEGIN
    SELECT 123456 AS [step_id], 'There are no step_id matching the WHERE clause' AS [step_name]
END

问题:,但是在这里我两次运行相同的SQL。我想知道是否有更好的方法可以做到这一点。

3 个答案:

答案 0 :(得分:3)

问题是,如果WHERE子句消除了所有行,那么最终将得到一个空集。

一种解决方法是,使用聚合函数将结果强制为一行。

然后,使用COALESCE(或ISNULL),可以分配默认值。

此解决方案仅在以下情况下可行:

  • 您的基本查询总是返回恰好0或1行
  • 您的列不包含NULL
  • 可以汇总所选列(例如,不适用于文本列)
  • 您的默认值与列具有相同的数据类型

例如:

select COALESCE(MAX(step_id),123456) AS step_id,
       COALESCE(MAX(step_name),'There are no step_id matching the WHERE clause') AS step_name
  from msdb.dbo.sysjobhistory
 where step_id = 9999

答案 1 :(得分:1)

这是完成同一件事的一种简单方法。不需要变量等。

<script>
import { mapActions, mapGetters } from "vuex";

export default {
    created: function() {
        console.log("created() - called");
        this.getUserCars();
    },
    mounted: function() {
        console.log("mounted() - called");
    },
    destroyed: function() {
        console.log("destroyed() - called");
    },
    watch: {
        userSites(newValue, oldValue) {
            console.log(`watch() Updating from ${oldValue} to ${newValue}`);

            const options = {
                data: {type: "local", source: this.userCars(), pageSize: 5},
                layout: {theme: "default", class: "", scroll: !1, footer: !1},
                sortable: !0,
                pagination: !0,
                columns: [
                    {field: "name", title: "Name"},
                    {field: "createdAt", title: "Created At"}
                ]
            };
            $('#m_datatable').mDatatable(options);

        },
    },
    computed: {

    },
    methods: {
        ...mapGetters(["userCars"]),
        ...mapActions(["getUserCars"]),
    }
};
</script>

答案 2 :(得分:1)

这是另一个选择,仅用于比较(如果没有主要结果,它将在与主要结果相同的表中返回您的虚拟行)。

DECLARE @search_ID INT = 999;

WITH data
AS (SELECT step_id, step_name
    FROM msdb.dbo.sysjobhistory
    UNION ALL
    SELECT 12345, 'dummy') --Insert your dummy data here

SELECT *
FROM data
WHERE step_id = @search_ID
      OR
      (   step_id = 12345
          AND NOT EXISTS (SELECT * FROM data WHERE step_id = @search_ID)
      );