明确引用不明确的列别名的最不繁琐的方法?



我正在从未设置的SQL Server数据库中获取一些数据。这是一个生产环境,所以我不想改变太多。

我正在获取数据并使用获取的数据填充各种类型的对象。某些对象只需要一个表中的数据;其他人需要联接才能获取所有必要的数据。

有很多表有一个时间戳列time,通常存储在datetimedatetimeoffset列类型中。这通常是查询应按列排序的依据。但是,有几个表,其中时间戳存储在ndate列(仅存储日期(和ntime列(仅存储时间(中。将这些值相加将产生正确的时间戳。

因此,要使此表的行为与其他表类似,并使列映射到对象属性,最简单和最明显的做法很简单:

SELECT *, (ndate + ntime) AS time 
FROM tableA 
WHERE x = z 
ORDER BY time DESC

这工作得很好。但是,如果对象是需要来自多个表的数据的对象之一,则会弹出一个明显的问题。如果tableA联接tableB而后者有一个time列,那么我无法弄清楚如何按别名time列对查询进行排序:

SELECT *, (ndate + ntime) AS time 
FROM tableA 
LEFT JOIN tableB 
WHERE x = z 
ORDER BY time DESC

– 产生一个通知,表明time是模棱两可的,当然是这样。

SELECT *, (ndate + ntime) AS time 
FROM tableA 
LEFT JOIN tableB 
WHERE x = z 
ORDER BY tableA.time DESC

– 产生一个通知,指出tableA.time是无效列,当然是这样,因为它不是表中实际存在的列。

当然,有各种或多或少繁琐的方法可以解决这个问题。我设法想出的最简单方法是将tableA(带有别名列("包装"在子查询中,然后子查询将具有可引用的别名,使列明确:

SELECT * 
FROM 
(SELECT *, (ndate + ntime) AS time 
FROM tableA) AS subTable 
LEFT JOIN tableB 
WHERE x = z 
ORDER BY subTable.time DESC

这就是我所说的相当简单的,但它仍然使查询的可读性比原始查询差得多,而原始查询非常简单。

显然,这不是你所说的严重问题,但它仍然让我怀疑是否有一种不那么"破坏性"的方式来实现相同的最终目标。

是否有一种侵入性更小的方法,它保留了原始查询的更多简单性?

您可以使用"交叉应用"或简单地使用原始表达式进行排序依据。 即:

SELECT *, (ndate + ntime) AS time 
FROM tableA 
LEFT JOIN tableB 
WHERE x = z 
ORDER BY (ndate + ntime) DESC;

注意:这里存在尝试使用 * 在结果集中创建多个"时间"列的问题。您可能会列出您想要的列(无论如何这是推荐的方式(。或者将您的"时间"命名为其他名称。

是的-ORDER BY 1将按您选择的第一列排序,无论它是什么。当然,如果您更改第一列的顺序,则更改顺序

SELECT (tableA.ndate + tableA.ntime) AS time, tableA.*, tableB.*
FROM tableA LEFT JOIN tableB WHERE x = z ORDER BY 1 DESC

由于您不知道*有多少列,因此您首先按列排序。

您可能希望添加为您创建time的计算列。

编辑

我不确定下面的评论中关于外部连接的混淆是什么。我在查询中添加了一些详细信息。

相关内容

  • 没有找到相关文章

最新更新