我正在尝试将“分组依据”添加到我的简单查询XML中。 我在下面的链接中看到了类似的问题,但是我无法用我的问题来弥补。
我的示例代码
DECLARE @xml VARCHAR(8000) = '<root><que trp=''100001'' ccid=''59748'' /></root>'
DECLARE @recordXml XML = @xml
SELECT
T.a.value('@trp[1]','CHAR(6)') AS trip_no,
MAX(T.a.value('@ccid[1]','INT')) AS check_call_id
FROM @recordXml.nodes('/root/que')T(a)
WHERE
LEN(T.a.value('@trp[1]','CHAR(6)')) = 6
AND ISNUMERIC(T.a.value('@trp[1]','CHAR(6)')) = 1
AND CONVERT(INT, T.a.value('@trp[1]','CHAR(6)')) > 0
GROUP BY T.a.value('@trp[1]','CHAR(6)')
感谢您提供任何帮助来解决此问题。
答案 0 :(得分:3)
使用子查询...
SELECT
trip_no,
MAX(check_call_id) AS check_call_id
FROM
(
SELECT
T.a.value('@trp[1]' , 'CHAR(6)') AS trip_no,
T.a.value('@ccid[1]', 'INT' ) AS check_call_id
FROM
@recordXml.nodes('/root/que')T(a)
WHERE
LEN(T.a.value('@trp[1]','CHAR(6)')) = 6
AND ISNUMERIC(T.a.value('@trp[1]','CHAR(6)')) = 1
AND CONVERT(INT, T.a.value('@trp[1]','CHAR(6)')) > 0
)
AS parsed_xml
GROUP BY
trip_no
答案 1 :(得分:1)
您需要将未聚合的查询包装在CTE或子查询中,然后对其进行聚合。例如:
WITH CTE AS
(SELECT T.a.value('@trp[1]', 'CHAR(6)') AS trip_no,
T.a.value('@ccid[1]', 'INT') AS check_call_id
FROM @recordXml.nodes('/root/que') T(a)
WHERE LEN(T.a.value('@trp[1]', 'CHAR(6)')) = 6
AND ISNUMERIC(T.a.value('@trp[1]', 'CHAR(6)')) = 1
AND CONVERT(int, T.a.value('@trp[1]', 'CHAR(6)')) > 0)
SELECT trip_no,
MAX(check_call_id)
FROM CTE
GROUP BY trip_no;
另一方面,我建议反对ISNUMERIC
,并建议使用TRY_CONVERT
。 ISNUMERIC
可能有一些奇怪的行为,例如为1
返回ISNUMERIC('.')
,但为'.'
转换为任何数值数据类型将失败。另外,如果ISNUMERIC
失败,则以下子句CONVERT(int, T.a.value('@trp[1]', 'CHAR(6)')) > 0
将会失败并出错。因此,您可以更加简洁地做到:
WITH CTE AS
(SELECT T.a.value('@trp[1]', 'CHAR(6)') AS trip_no,
T.a.value('@ccid[1]', 'INT') AS check_call_id
FROM @recordXml.nodes('/root/que') T(a)
WHERE LEN(T.a.value('@trp[1]', 'CHAR(6)')) = 6
AND TRY_CONVERT(int,T.a.value('@trp[1]', 'CHAR(6)')) > 0) --If this has decimals, use decimal instead of int
SELECT trip_no,
MAX(check_call_id) AS check_call_id
FROM CTE
GROUP BY trip_no;
答案 2 :(得分:0)
DECLARE @xml VARCHAR(8000) = '<root><que trp=''100001'' ccid=''59748'' /></root>'
DECLARE @recordXml XML = @xml
SELECT
dat.trip_no
, MAX( dat.check_call_id ) AS max_check_call_id
FROM (
SELECT
T.a.value( '@trp[1]','CHAR(6)' ) AS trip_no,
T.a.value( '@ccid[1]','INT' ) AS check_call_id
FROM @recordXml.nodes( '/root/que' ) T( a )
WHERE
LEN( T.a.value('@trp[1]','CHAR(6)') ) = 6
AND ISNUMERIC( T.a.value( '@trp[1]','CHAR(6)' ) ) = 1
AND CONVERT( INT, T.a.value( '@trp[1]','CHAR(6)' ) ) > 0
) AS dat
GROUP BY
dat.trip_no