我在这里有这部分查询:
(
SELECT ROW_NUMBER() OVER (ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS 'SortOrder'
FOR XML PATH(''), Type
)
这是针对XML的。我的问题是ROW_NUMBER()
总是返回1,为什么不为每行返回不同的数字呢?
完整查询:
Select
(
Select cast ('<'+ V_CONSTAT_ACTUAL_DATES.JOB_NUMBER + '>' +
cast(
(Select
(
SELECT CONVERT(date, V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS 'closingDate'
FOR XML PATH(''), Type
),
(
SELECT DATEDIFF(dd,V_CONSTAT_BASE_DATES.ID67,V_CONSTAT_ACTUAL_DATES.DATE_TO_END)-1 AS 'DaysOfConstruction'
FOR XML PATH(''), Type
),
(
SELECT DATEDIFF(dd,GETDATE(),V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS 'DaysToClosing'
FOR XML PATH(''), Type
),
(
SELECT
CASE WHEN COALESCE(V_CONSTAT_ACTUAL_DATES.IDNOTES2, '') = '' THEN ' ' ELSE V_CONSTAT_ACTUAL_DATES.IDNOTES2 END AS 'notes'
FOR XML PATH(''), Type
),
(
SELECT DATEDIFF(dd,V_CONSTAT_BASE_DATES.ID187,V_CONSTAT_PROJ_DATES.ID187) AS 'ScheduleVariance'
FOR XML PATH(''), Type
),
(
SELECT SortOrder FROM
(SELECT ROW_NUMBER() OVER
(ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END)
AS 'SortOrder') AS SubQuery
FOR XML PATH(''), Type
)
for xml path(''))
as varchar(max)
)
+ '</'+ V_CONSTAT_ACTUAL_DATES.JOB_NUMBER + '>'
as xml)
)
from ((homefront.dbo.V_CONSTAT_PROJ_DATES V_CONSTAT_PROJ_DATES INNER JOIN homefront.dbo.V_CONSTAT_ACTUAL_DATES V_CONSTAT_ACTUAL_DATES
ON
V_CONSTAT_PROJ_DATES.JOB_NUMBER=V_CONSTAT_ACTUAL_DATES.JOB_NUMBER)
INNER JOIN
homefront.dbo.V_CONSTAT_BASE_DATES V_CONSTAT_BASE_DATES
ON
(V_CONSTAT_ACTUAL_DATES.JOB_NUMBER=V_CONSTAT_BASE_DATES.JOB_NUMBER) AND (V_CONSTAT_PROJ_DATES.JOB_NUMBER=V_CONSTAT_BASE_DATES.JOB_NUMBER))
INNER JOIN
homefront.dbo.V_CONSTAT_SCH_DATES V_CONSTAT_SCH_DATES
ON
((V_CONSTAT_BASE_DATES.JOB_NUMBER=V_CONSTAT_SCH_DATES.JOB_NUMBER) AND (V_CONSTAT_PROJ_DATES.JOB_NUMBER=V_CONSTAT_SCH_DATES.JOB_NUMBER))
AND (V_CONSTAT_ACTUAL_DATES.JOB_NUMBER=V_CONSTAT_SCH_DATES.JOB_NUMBER)
WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC = 'Ancaster Augusta Ph 4(A) Condos' AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
FOR XML PATH(''), ROOT('Root')
答案 0 :(得分:4)
您将ROW_NUMBER()
放在标量子查询中只有一行:
(SELECT ROW_NUMBER() OVER
(ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END)
AS 'SortOrder')
您可能认为ORDER BY
子句(引用外部查询中的列)对此处的ROW_NUMBER()
计算有任何影响。它没有。此子查询返回一行,该行唯一合理的ROW_NUMBER
始终为1
。
解决方案是尽可能延迟将结果转换为XML,并且只需通过顶层ROW_NUMBER()
的{{1}}计算选择您的数据。
答案 1 :(得分:1)
您可以根据需要使用子查询。尝试这样的事情:
SELECT SortOrder FROM
(SELECT ROW_NUMBER() OVER
(ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END)
AS 'SortOrder') AS SubQuery
FOR XML PATH(''), Type
编辑: 在查看完整查询后,我可以向您推荐另一种解决方案。
Actualy你将在subselect中拥有所有查询逻辑,并且ROW_NUMBER()函数将完美运行。外部部分将涵盖XML格式的查询。
<强> P.S。更多解释:
SELECT (
SELECT CAST('<'+JOB_NUMBER + '>' +
CAST((SELECT
(SELECT closingDate FOR XML PATH(''), Type),
(SELECT DaysOfConstruction FOR XML PATH(''), Type),
(SELECT DaysToClosing FOR XML PATH(''), Type),
(SELECT notes FOR XML PATH(''), Type),
(SELECT ScheduleVariance FOR XML PATH(''), Type),
(SELECT SortOrder FOR XML PATH(''), Type)
FOR XML PATH('')) AS VARCHAR(MAX))
+ '</'+ JOB_NUMBER + '>' as xml))
FROM
(SELECT
V_CONSTAT_ACTUAL_DATES.JOB_NUMBER,
CONVERT(date, V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS closingDate,
DATEDIFF(dd, V_CONSTAT_BASE_DATES.ID67,V_CONSTAT_ACTUAL_DATES.DATE_TO_END) - 1 AS DaysOfConstruction,
DATEDIFF(dd, GETDATE(),V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS DaysToClosing,
(CASE WHEN COALESCE(V_CONSTAT_ACTUAL_DATES.IDNOTES2, '') = '' THEN ' ' ELSE V_CONSTAT_ACTUAL_DATES.IDNOTES2 END) AS notes,
DATEDIFF(dd, V_CONSTAT_BASE_DATES.ID187,V_CONSTAT_PROJ_DATES.ID187) AS ScheduleVariance,
ROW_NUMBER() OVER (ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS SortOrder
FROM homefront.dbo.V_CONSTAT_PROJ_DATES V_CONSTAT_PROJ_DATES
INNER JOIN homefront.dbo.V_CONSTAT_ACTUAL_DATES V_CONSTAT_ACTUAL_DATES ON V_CONSTAT_PROJ_DATES.JOB_NUMBER=V_CONSTAT_ACTUAL_DATES.JOB_NUMBER
INNER JOIN homefront.dbo.V_CONSTAT_BASE_DATES V_CONSTAT_BASE_DATES ON
V_CONSTAT_ACTUAL_DATES.JOB_NUMBER=V_CONSTAT_BASE_DATES.JOB_NUMBER AND V_CONSTAT_PROJ_DATES.JOB_NUMBER=V_CONSTAT_BASE_DATES.JOB_NUMBER
INNER JOIN homefront.dbo.V_CONSTAT_SCH_DATES V_CONSTAT_SCH_DATES ON
V_CONSTAT_BASE_DATES.JOB_NUMBER=V_CONSTAT_SCH_DATES.JOB_NUMBER AND V_CONSTAT_PROJ_DATES.JOB_NUMBER=V_CONSTAT_SCH_DATES.JOB_NUMBER
AND V_CONSTAT_ACTUAL_DATES.JOB_NUMBER=V_CONSTAT_SCH_DATES.JOB_NUMBER
WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC = 'AnCASTer Augusta Ph 4(A) Condos' AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()) AS SubQuery
ORDER BY closingDate
FOR XML PATH(''), ROOT('Root')
答案 2 :(得分:1)
通过派生表使用分析函数是很常见的,以便生成列,然后通过列别名由后续子句访问。当需要在where子句中使用row_number()时,这种情况尤为常见。 e.g。
select * from (select *
, row_number(partition by X order by Y) as rn
from table1
) as d
where d.rn = 1
这里我相信相同的逻辑适用,您想要计算排序顺序列然后将数据放入XML结果。我的猜测是你要按作业号进行分区。
FROM (
SELECT
*
, ROW_NUMBER() OVER (PARTITION BY V_CONSTAT_ACTUAL_DATES.JOB_NUMBER
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS 'SortOrder'
FROM homefront.dbo.V_CONSTAT_PROJ_DATES V_CONSTAT_PROJ_DATES
INNER JOIN homefront.dbo.V_CONSTAT_ACTUAL_DATES V_CONSTAT_ACTUAL_DATES ON V_CONSTAT_PROJ_DATES.JOB_NUMBER = V_CONSTAT_ACTUAL_DATES.JOB_NUMBER
INNER JOIN homefront.dbo.V_CONSTAT_BASE_DATES V_CONSTAT_BASE_DATES ON V_CONSTAT_ACTUAL_DATES.JOB_NUMBER = V_CONSTAT_BASE_DATES.JOB_NUMBER
AND V_CONSTAT_PROJ_DATES.JOB_NUMBER = V_CONSTAT_BASE_DATES.JOB_NUMBER
INNER JOIN homefront.dbo.V_CONSTAT_SCH_DATES V_CONSTAT_SCH_DATES ON V_CONSTAT_BASE_DATES.JOB_NUMBER = V_CONSTAT_SCH_DATES.JOB_NUMBER
AND V_CONSTAT_PROJ_DATES.JOB_NUMBER = V_CONSTAT_SCH_DATES.JOB_NUMBER
AND V_CONSTAT_ACTUAL_DATES.JOB_NUMBER = V_CONSTAT_SCH_DATES.JOB_NUMBER
WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC = 'Ancaster Augusta Ph 4(A) Condos'
AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END >= GETDATE()
) AS d
并作为完整查询:
SELECT (
SELECT
CAST('<' + V_CONSTAT_ACTUAL_DATES.JOB_NUMBER + '>' +
CAST((
SELECT (
SELECT
CONVERT(date, d.DATE_TO_END) AS 'closingDate'
FOR xml PATH (''), TYPE
)
, (
SELECT
DATEDIFF(dd, d.ID67, V_CONSTAT_ACTUAL_DATES.DATE_TO_END) - 1 AS 'DaysOfConstruction'
FOR xml PATH (''), TYPE
)
, (
SELECT
DATEDIFF(dd, GETDATE(), d.DATE_TO_END) AS 'DaysToClosing'
FOR xml PATH (''), TYPE
)
, (
SELECT
CASE
WHEN COALESCE(d.IDNOTES2, '') = '' THEN ' '
ELSE d.IDNOTES2
END AS 'notes'
FOR xml PATH (''), TYPE
)
, (
SELECT
DATEDIFF(dd, d.ID187, d.ID187) AS 'ScheduleVariance'
FOR xml PATH (''), TYPE
)
, (
SELECT
SortOrder
FROM (
SELECT
d.SortOrder
) AS SubQuery
FOR xml PATH (''), TYPE
)
FOR xml PATH ('')
)
AS varchar(max)
)
+ '</' + V_CONSTAT_ACTUAL_DATES.JOB_NUMBER + '>'
AS xml)
)
FROM (
SELECT
*
, ROW_NUMBER() OVER (PARTITION BY V_CONSTAT_ACTUAL_DATES.JOB_NUMBER
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS "SortOrder"
FROM homefront.dbo.V_CONSTAT_PROJ_DATES V_CONSTAT_PROJ_DATES
INNER JOIN homefront.dbo.V_CONSTAT_ACTUAL_DATES V_CONSTAT_ACTUAL_DATES ON V_CONSTAT_PROJ_DATES.JOB_NUMBER = V_CONSTAT_ACTUAL_DATES.JOB_NUMBER
INNER JOIN homefront.dbo.V_CONSTAT_BASE_DATES V_CONSTAT_BASE_DATES ON V_CONSTAT_ACTUAL_DATES.JOB_NUMBER = V_CONSTAT_BASE_DATES.JOB_NUMBER
AND V_CONSTAT_PROJ_DATES.JOB_NUMBER = V_CONSTAT_BASE_DATES.JOB_NUMBER
INNER JOIN homefront.dbo.V_CONSTAT_SCH_DATES V_CONSTAT_SCH_DATES ON V_CONSTAT_BASE_DATES.JOB_NUMBER = V_CONSTAT_SCH_DATES.JOB_NUMBER
AND V_CONSTAT_PROJ_DATES.JOB_NUMBER = V_CONSTAT_SCH_DATES.JOB_NUMBER
AND V_CONSTAT_ACTUAL_DATES.JOB_NUMBER = V_CONSTAT_SCH_DATES.JOB_NUMBER
WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC = 'Ancaster Augusta Ph 4(A) Condos'
AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END >= GETDATE()
) AS d
ORDER BY
V_CONSTAT_ACTUAL_DATES.DATE_TO_END
FOR xml PATH (''), ROOT ('Root')
答案 3 :(得分:1)
我的问题是ROW_NUMBER()总是返回1,怎么回事 为每一行返回不同的数字?
<强>原因强>
1)原因是跟随子查询
(
SELECT ROW_NUMBER() OVER (ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END) AS 'SortOrder'
FOR XML PATH(''), Type
)
与
相同(
SELECT ROW_NUMBER() OVER (ORDER BY a.b) AS 'SortOrder'
FROM (VALUES
(V_CONSTAT_ACTUAL_DATES.DATE_TO_END) -- one column / one row
) AS a(b)
或
(
SELECT ROW_NUMBER() OVER (ORDER BY a.b) AS 'SortOrder'
FROM (
SELECT V_CONSTAT_ACTUAL_DATES.DATE_TO_END -- one column / one row
) AS a(b)
这意味着以上所有子查询都将一个数据集作为数据源,其中一列,(最重要的是)一行。这就是ROW_NUMBER
始终返回1
的原因:因为当前子查询始终只有一个源行。
2)更多,下一个查询返回相同的结果
SELECT *,
(
SELECT ROW_NUMBER() OVER (ORDER BY a.b) AS 'SortOrder'
FROM (VALUES
(V_CONSTAT_ACTUAL_DATES.DATE_TO_END) -- one column / one row
) AS a(b)
FOR XML PATH(''), Type
) AS XMLCOLUMN
FROM (VALUES
('A', '20160302'),
('B', '20160202'),
('C', '20160101')
) V_CONSTAT_ACTUAL_DATES(CODE, DATE_TO_END)
SELECT *,
(
SELECT ROW_NUMBER() OVER (ORDER BY a.b) AS 'SortOrder'
FROM (
SELECT V_CONSTAT_ACTUAL_DATES.DATE_TO_END -- one column / one row
) AS a(b)
FOR XML PATH(''), Type
) AS XMLCOLUMN
FROM (VALUES
('A', '20160302'),
('B', '20160202'),
('C', '20160101')
) V_CONSTAT_ACTUAL_DATES(CODE, DATE_TO_END)
结果
CODE DATE_TO_END XMLCOLUMN
---- ----------- ------------------------
A 20160302 <SortOrder>1</SortOrder>
B 20160202 <SortOrder>1</SortOrder>
C 20160101 <SortOrder>1</SortOrder>
并且具有相同(几乎)的执行计划,具有相同的估计查询成本(33%):
一种解决方案可能是包含ROW_NUMBER' within
V_CONSTAT_ACTUAL_DATES`视图。
注意/友好警告:请不要使用列值连接<
,>
以生成所需的XML数据!我只会使用FOR XML
。如果您想解决此问题,请发布另一个问题。