MSSQL Order by date with distinct
MSSQL Order by date with distinct
我在下面有这个查询段,我试图从这个 table 中的日期字段构建 "month-year" 的字符串。从当前月份开始,往后 12 个月,它以正确的顺序出现非常重要。
DECLARE @cols AS NVARCHAR(MAX)
SELECT @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT CONVERT(char(3), StartDate, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(StartDate)), 2) AS y
FROM Products2
) AS Y
--ORDER BY y desc
FOR XML PATH('')),
1, 1, N'')
这个查询没有按正确的顺序提取日期,我想看看你们是否知道任何巧妙的技巧来按正确的顺序提取日期。我可以引入 startDate 列并按它进行排序,但它会引入重复项,因为它可能在同一个月有多个条目。我在这里 http://sqlfiddle.com/#!6/3a500/5
创建了一个示例 table
你可以使用
DECLARE @cols AS NVARCHAR(MAX);
SELECT @cols = STUFF((SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT CONVERT(CHAR(3), StartDate, 0) + '-'
+ RIGHT(CONVERT(VARCHAR, YEAR(StartDate)), 2) AS y,
MIN(StartDate) AS z
FROM Products2
GROUP BY CONVERT(CHAR(3), StartDate, 0) + '-'
+ RIGHT(CONVERT(VARCHAR, YEAR(StartDate)), 2)) AS Y
ORDER BY z
FOR XML PATH('')), 1, 1, N'');
SELECT @cols;
如果您正在使用 SQL Server 2012+
,您可以使用 FORMAT
函数:
DECLARE @cols AS NVARCHAR(MAX);
;WITH cte AS -- get only one date per month/year
(
SELECT MIN(StartDate) AS StartDate
FROM #Products2
GROUP BY YEAR(StartDate),MONTH(StartDate)
)
SELECT @cols = STUFF((SELECT ',' + QUOTENAME(FORMAT(StartDate, 'MMM-yy'))
FROM cte
ORDER BY StartDate
FOR XML PATH('')),
1, 1, N'');
SELECT @cols;
输出:
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ result ║
╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ [Dec-15],[Jan-16],[Feb-16],[Mar-16],[Apr-16],[May-16],[Jun-16],[Jul-16],[Aug-16],[Sep-16],[Oct-16],[Nov-16],[Dec-16] ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
您似乎刚刚获得 month/year,因此我们可以截断到该月的第一天并将其包含在查询中。
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
现在我们可以通过它来订购了:
DECLARE @cols AS NVARCHAR(MAX);
SELECT @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (
SELECT DISTINCT CONVERT(char(3), StartDate, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(StartDate)), 2) AS y,
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
FROM Products2
) AS Y
ORDER BY monthStart
FOR XML PATH('')),
1, 1, N'');
select @cols;
这是输出:
[Dec-15],[Jan-16],[Feb-16],[Mar-16],[Apr-16],[May-16],[Jun-16],[Jul-16],[Aug-16],[Sep-16],[Oct-16],[Nov-16],[Dec-16]
这就是您要找的吗?这是 fiddle:
http://sqlfiddle.com/#!6/3a500/67
更好的是,只需 select 不同的月份开始日期,然后仅对其进行字符串转换。
DECLARE @cols AS NVARCHAR(MAX);
SELECT @cols = STUFF(
(SELECT N',' + QUOTENAME(CONVERT(char(3), monthStart, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(monthStart)), 2)) AS [text()]
FROM (
SELECT DISTINCT
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
FROM Products2
) AS Y
ORDER BY monthStart
FOR XML PATH('')),
1, 1, N'');
select @cols;
这是 fiddle:
http://sqlfiddle.com/#!6/3a500/72
我在下面有这个查询段,我试图从这个 table 中的日期字段构建 "month-year" 的字符串。从当前月份开始,往后 12 个月,它以正确的顺序出现非常重要。
DECLARE @cols AS NVARCHAR(MAX)
SELECT @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT CONVERT(char(3), StartDate, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(StartDate)), 2) AS y
FROM Products2
) AS Y
--ORDER BY y desc
FOR XML PATH('')),
1, 1, N'')
这个查询没有按正确的顺序提取日期,我想看看你们是否知道任何巧妙的技巧来按正确的顺序提取日期。我可以引入 startDate 列并按它进行排序,但它会引入重复项,因为它可能在同一个月有多个条目。我在这里 http://sqlfiddle.com/#!6/3a500/5
创建了一个示例 table你可以使用
DECLARE @cols AS NVARCHAR(MAX);
SELECT @cols = STUFF((SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT CONVERT(CHAR(3), StartDate, 0) + '-'
+ RIGHT(CONVERT(VARCHAR, YEAR(StartDate)), 2) AS y,
MIN(StartDate) AS z
FROM Products2
GROUP BY CONVERT(CHAR(3), StartDate, 0) + '-'
+ RIGHT(CONVERT(VARCHAR, YEAR(StartDate)), 2)) AS Y
ORDER BY z
FOR XML PATH('')), 1, 1, N'');
SELECT @cols;
如果您正在使用 SQL Server 2012+
,您可以使用 FORMAT
函数:
DECLARE @cols AS NVARCHAR(MAX);
;WITH cte AS -- get only one date per month/year
(
SELECT MIN(StartDate) AS StartDate
FROM #Products2
GROUP BY YEAR(StartDate),MONTH(StartDate)
)
SELECT @cols = STUFF((SELECT ',' + QUOTENAME(FORMAT(StartDate, 'MMM-yy'))
FROM cte
ORDER BY StartDate
FOR XML PATH('')),
1, 1, N'');
SELECT @cols;
输出:
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ result ║
╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ [Dec-15],[Jan-16],[Feb-16],[Mar-16],[Apr-16],[May-16],[Jun-16],[Jul-16],[Aug-16],[Sep-16],[Oct-16],[Nov-16],[Dec-16] ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
您似乎刚刚获得 month/year,因此我们可以截断到该月的第一天并将其包含在查询中。
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
现在我们可以通过它来订购了:
DECLARE @cols AS NVARCHAR(MAX);
SELECT @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (
SELECT DISTINCT CONVERT(char(3), StartDate, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(StartDate)), 2) AS y,
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
FROM Products2
) AS Y
ORDER BY monthStart
FOR XML PATH('')),
1, 1, N'');
select @cols;
这是输出:
[Dec-15],[Jan-16],[Feb-16],[Mar-16],[Apr-16],[May-16],[Jun-16],[Jul-16],[Aug-16],[Sep-16],[Oct-16],[Nov-16],[Dec-16]
这就是您要找的吗?这是 fiddle: http://sqlfiddle.com/#!6/3a500/67
更好的是,只需 select 不同的月份开始日期,然后仅对其进行字符串转换。
DECLARE @cols AS NVARCHAR(MAX);
SELECT @cols = STUFF(
(SELECT N',' + QUOTENAME(CONVERT(char(3), monthStart, 0) + '-' +
RIGHT(CONVERT(varchar, YEAR(monthStart)), 2)) AS [text()]
FROM (
SELECT DISTINCT
DATEADD(month, DATEDIFF(month, 0, StartDate), 0) monthStart
FROM Products2
) AS Y
ORDER BY monthStart
FOR XML PATH('')),
1, 1, N'');
select @cols;
这是 fiddle: http://sqlfiddle.com/#!6/3a500/72