【问题标题】:How to have totals row to be exlcuded from order by and show on bottom of table ssms18如何将总计行从 order by 中排除并显示在表 ssms 18 的底部
【发布时间】:2021-10-14 14:57:45
【问题描述】:

这是我现在的代码。输出表中有 4 行,我想知道如何在表底部显示总计行。由于 DESC 的顺序,它目前显示在顶部。

USE [MyData]

SELECT * INTO tableOne FROM [DataLib].[dbo].[Lease] -- carry over Lease table from Data Library to Reporting Database

--populate new table with the 3 commerical sectors and their uniqu
CREATE TABLE commercial_expirations (
    UniqueID varchar(255),
    PropertyType varchar(50))

INSERT INTO commercial_expirations
VALUES  ('Asset / Most Recent Quarter / All Assets / Sector | Industrial','Industrial'),
        ('Asset / Most Recent Quarter / All Assets / Sector | Office','Office'),
        ('Asset / Most Recent Quarter / All Assets / Sector | Retail','Retail'),
        ('Asset / Most Recent Quarter / All Assets / SectorType | Commercial','Total')

SELECT  c.PropertyType AS 'Property Type',
        e.SpaceArea_End AS 'RentableSF',
        FORMAT(e.LsDuration_WAvg, 'N1') AS 'WA Duration (Yrs)',
        FORMAT(e.[LsArea%_End], 'P1') AS '%Leased',
        FORMAT(e.[Year0ExpireArea%], 'P1') AS '2021',
        FORMAT(e.[Year1ExpireArea%], 'P1') AS '2022',
        FORMAT(e.[Year2ExpireArea%], 'P1') AS '2023',
        FORMAT(e.[Year3ExpireArea%], 'P1') AS '2024',
        FORMAT(e.[Year4ExpireArea%], 'P1') AS '2025',
        FORMAT(iif(e.[Year5ExpireArea%] IS NULL, 0, e.[Year5ExpireArea%]) + iif(e.[Year6ExpireArea%] IS NULL, 0, e.[Year6ExpireArea%]) + iif(e.[Year7ExpireArea%] IS NULL, 0, e.[Year7ExpireArea%]) + iif(e.[Year8ExpireArea%] IS NULL, 0, e.[Year8ExpireArea%]) + iif(e.[Year9ExpireArea%] IS NULL, 0, e.[Year9ExpireArea%])  + iif(e.[Year10ExpireArea%] IS NULL, 0, e.[Year10ExpireArea%]) + iif(e.[Year11PlusExpireArea%] IS NULL, 0, e.[Year11PlusExpireArea%]), 'P1')  AS 'Thereafter'

INTO ##Schedule

FROM commercial_expirations AS c
LEFT JOIN tableOne AS e
ON c.UniqueID = e.RecordID;

SELECT  [Property Type],
        FORMAT(RentableSF, 'N0') AS 'Rentable SF',
        [WA Duration (Yrs)],
        [2021],
        [2022],
        [2023],
        [2024],
        [2025],
        Thereafter

FROM ##Schedule
ORDER BY [RentableSF] DESC;



/*
DROP TABLE commercial_expirations
DROP TABLE expSummary
DROP TABLE ##Schedule
*/

【问题讨论】:

  • order by case when...
  • 在 ORDER BY 子句中添加case [Property Type] when 'Total' then 1 else 0 end 作为第一个条件。
  • @stu 如果我要使用它,不包括名称为总的行的语法是什么?
  • 为什么需要所有这些临时表?为什么不只是一个查询?
  • INTO ##Schedule 为什么这里需要一个全局临时表?是为了保证两个人不能同时运行这个查询吗? ##global 的真实用例很少,我建议坚持使用 #local

标签: sql-server ssms


【解决方案1】:

这是我将所有这些代码转换为单个查询的最佳尝试。由于我没有数据库、架构或脚本来验证查询,因此我将调试留给您。

with commercial_expirations as (
   select * from (
   VALUES  ('Asset / Most Recent Quarter / All Assets / Sector | Industrial',    'Industrial'),
           ('Asset / Most Recent Quarter / All Assets / Sector | Office',        'Office'),
           ('Asset / Most Recent Quarter / All Assets / Sector | Retail',        'Retail'),
           ('Asset / Most Recent Quarter / All Assets / SectorType | Commercial','Total')
   ) as x(UniqueID, PropertyType)
)
select ... 
from commercial_expirations as cexp
left join [DataLib].[dbo].[Lease] as lease -- why use a three-part name here? THINK!! 
  ON cexp.UniqueID = lease.RecordID
order by 
    case cexp.PropertyType when 'Total' then 1 else 0 end, 
    lease.SpaceArea_End DESC
;

小心使用由三部分组成的名称。它使您的代码变得脆弱,因为它需要在使用不同的环境时进行更改。一般来说,您的连接应确定用于对象(表)引用的数据库。我建议你真的在 sql 查询中使用 FORMAT,因为它是一项昂贵的操作。格式化是表现层最好的功能。

最后的建议。停止使用这种

经常看到人们使用该模式只是将这些脚本推送到生产环境并继续执行下一个任务——从不尝试清理或优化它。这只会强化坏习惯。开始学习良好的习惯。

【讨论】:

  • 哇,这太棒了。我想说我这次的方法非常快速和肮脏,只是为了得到正确的输出。现在我已经到了那里,我会回去优化。
【解决方案2】:

要将总行强制到顶部,您可以添加

  CASE WHEN c.PropertyType = 'Total' THEN 1 ELSE 2 END

ORDER BY 子句的开头。

您还可以通过多种方式简化和改进此查询:

  • commercial_expirations 更改为 CTE 中的虚拟表
  • 将临时表组合到一个查询中
  • 使用ISNULL 而不是IIF(... IS NULL
  • 使用[] 引用列名
    • 理想情况下,您根本不需要引用列名,请谨慎选择名称
  • 按实际值排序,而不是按格式表示
WITH commercial_expirations AS (
    SELECT *
    FROM (VALUES  
        ('Asset / Most Recent Quarter / All Assets / Sector | Industrial','Industrial'),
        ('Asset / Most Recent Quarter / All Assets / Sector | Office','Office'),
        ('Asset / Most Recent Quarter / All Assets / Sector | Retail','Retail'),
        ('Asset / Most Recent Quarter / All Assets / SectorType | Commercial','Total')
    ) v(UniqueID, PropertyType)
)
SELECT  c.PropertyType AS [Property Type],
        FORMAT(e.SpaceArea_End, 'N0') AS RentableSF,
        FORMAT(e.LsDuration_WAvg, 'N1') AS [WA Duration (Yrs)],
        FORMAT(e.[LsArea%_End], 'P1') AS [%Leased],
        FORMAT(e.[Year0ExpireArea%], 'P1') AS [2021],
        FORMAT(e.[Year1ExpireArea%], 'P1') AS [2022],
        FORMAT(e.[Year2ExpireArea%], 'P1') AS [2023],
        FORMAT(e.[Year3ExpireArea%], 'P1') AS [2024],
        FORMAT(e.[Year4ExpireArea%], 'P1') AS [2025],
        FORMAT(
            ISNULL(e.[Year5ExpireArea%], 0) +
            ISNULL(e.[Year5ExpireArea%], 0) +
            ISNULL(e.[Year6ExpireArea%], 0) +
            ISNULL(e.[Year7ExpireArea%], 0) +
            ISNULL(e.[Year8ExpireArea%], 0) +
            ISNULL(e.[Year9ExpireArea%], 0) + 
            ISNULL(e.[Year10ExpireArea%], 0) + 
            ISNULL(e.[Year11PlusExpireArea%], 0), 'P1')  AS [Thereafter]
FROM commercial_expirations AS c
LEFT JOIN tableOne AS e
  ON c.UniqueID = e.RecordID;
ORDER BY
  CASE WHEN c.PropertyType = 'Total' THEN 1 ELSE 2 END,
  e.SpaceArea_End DESC;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 2015-03-03
    • 2018-10-26
    • 1970-01-01
    • 2016-11-12
    • 2011-08-24
    • 2015-03-19
    相关资源
    最近更新 更多