SQL 将日期时间作为具有数量字段的列进行透视
SQL Pivot with Datetime as a Column with quantity fields
我在我的数据库上有一个 SQL 视图,用于使用 Lot 和 PartNumberId 打印关于 C# 和 Itext7 的报告以查找结果
DECLARE @LotId int = '1'
DECLARE @PartNumerId int = '100'
SELECT * FROM vw_report_diarydefects WHERE LotId = @LotId AND PartNumerId = @PartNumerId
很多
零件编号
部件号
缺陷编号
缺陷
数量
排序日期
1
100
WD40
1
坏了
9
2019-10-01 10:31:02.000
1
100
WD40
2
油漆划痕
10
2019-10-02 10:31:02.000
1
100
WD40
3
肿
8
2019-10-02 10:31:02.000
1
100
WD40
2
油漆划痕
10
2019-10-03 10:31:02.000
1
100
WD40
4
弯曲
5
2019-10-04 10:31:02.000
我想要做的是将 SortingDate 作为列并在其上添加数量,如下所示:
缺陷
2019-10-01 10:31:02.000
2019-10-02 10:31:02.000
2019-10-03 10:31:02.000
2019-10-04 10:31:02.000
坏了
9
0
0
0
油漆划痕
0
10
10
0
肿
0
8
0
0
弯曲
0
0
0
5
我使用了 pivot(我第一次使用它)并且我已经使用了这个:
DECLARE @StuffColumn varchar(max)
DECLARE @sql varchar(max)
DECLARE @LotId int = '1'
DECLARE @PartNumerId int = '100'
SELECT @StuffColumn = STUFF((SELECT distinct ','+QUOTENAME(SortingDate)
FROM vw_report_diarydefects
WHERE LotId = @LotId AND PartNumerId = @PartNumerId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @SQL = ' select Defect, '+ @StuffColumn +'
from
(
select SortingDate,Defect,Qty
from vw_report_diarydefects
where LotId = ''' + CONVERT(NVARCHAR(50), @LotId, 121)+ ''' and PartNumerId = ''' + CONVERT(NVARCHAR(50), @PartNumerId, 121)+ '''
)x
pivot
(
Sum(Qty)
for SortingDate in( '+@StuffColumn+' )
)p'
EXEC(@SQL)
得到这个:
缺陷
2019 年 10 月 1 日10:31AM
2019 年 10 月 2 日10:31AM
2019 年 10 月 3 日10:31AM
2019 年 10 月 4 日10:31AM
坏了
空
空
空
空
油漆划痕
空
空
空
空
肿
空
空
空
空
弯曲
空
空
空
空
有没有办法用数量数据填充日期列?我是第一次使用 Pivot,我正在阅读该说明,但我仍有一些疑问。
尝试以下操作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication193
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Lot",typeof(int));
dt.Columns.Add("PartNumberId",typeof(int));
dt.Columns.Add("PartNumber",typeof(string));
dt.Columns.Add("DefectId",typeof(int));
dt.Columns.Add("Defect",typeof(string));
dt.Columns.Add("Qty", typeof(int));
dt.Columns.Add("SortingDate", typeof(DateTime));
dt.Rows.Add(new object[] {1, 100, "WD40", 1, "Broken", 9, DateTime.Parse("2019-10-01 10:31:02.000")});
dt.Rows.Add(new object[] {1, 100, "WD40", 2, "Paint Scratch", 10, DateTime.Parse("2019-10-02 10:31:02.000")});
dt.Rows.Add(new object[] {1, 100, "WD40", 3, "Swollen", 8, DateTime.Parse("2019-10-02 10:31:02.000")});
dt.Rows.Add(new object[] {1, 100, "WD40", 2, "Paint Scratch", 10, DateTime.Parse("2019-10-03 10:31:02.000")});
dt.Rows.Add(new object[] {1, 100, "WD40", 4, "Bent", 5, DateTime.Parse("2019-10-04 10:31:02.000")});
DateTime[] dates = dt.AsEnumerable().Select(x => x.Field<DateTime>("SortingDate")).OrderBy(x => x).Distinct().ToArray();
DataTable pivot = new DataTable();
pivot.Columns.Add("Defect");
foreach (DateTime date in dates)
{
pivot.Columns.Add(date.ToString(), typeof(int));
}
foreach(var defect in dt.AsEnumerable().GroupBy(x => x.Field<string>("Defect")))
{
DataRow newRow = pivot.Rows.Add();
newRow["Defect"] = defect.Key;
foreach (DataRow row in defect)
{
int qty = row.Field<int>("Qty");
DateTime date = row.Field<DateTime>("SortingDate");
newRow[date.ToString()] = qty;
}
}
}
}
}
这是我的发现。 Quotename
更改日期格式的方式是问题所在。将您的 @StuffColumn 数据更改为先转换为 varchar,然后引用它。
SELECT @StuffColumn = STUFF((SELECT distinct ','+QUOTENAME(CONVERT(NVARCHAR(50),SortingDate, 121))
FROM vw_report_diarydefects
WHERE Lot = @LotId AND PartNumberId = @PartNumerId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
这是SQL Fiddle。
我在我的数据库上有一个 SQL 视图,用于使用 Lot 和 PartNumberId 打印关于 C# 和 Itext7 的报告以查找结果
DECLARE @LotId int = '1'
DECLARE @PartNumerId int = '100'
SELECT * FROM vw_report_diarydefects WHERE LotId = @LotId AND PartNumerId = @PartNumerId
很多 | 零件编号 | 部件号 | 缺陷编号 | 缺陷 | 数量 | 排序日期 |
---|---|---|---|---|---|---|
1 | 100 | WD40 | 1 | 坏了 | 9 | 2019-10-01 10:31:02.000 |
1 | 100 | WD40 | 2 | 油漆划痕 | 10 | 2019-10-02 10:31:02.000 |
1 | 100 | WD40 | 3 | 肿 | 8 | 2019-10-02 10:31:02.000 |
1 | 100 | WD40 | 2 | 油漆划痕 | 10 | 2019-10-03 10:31:02.000 |
1 | 100 | WD40 | 4 | 弯曲 | 5 | 2019-10-04 10:31:02.000 |
我想要做的是将 SortingDate 作为列并在其上添加数量,如下所示:
缺陷 | 2019-10-01 10:31:02.000 | 2019-10-02 10:31:02.000 | 2019-10-03 10:31:02.000 | 2019-10-04 10:31:02.000 |
---|---|---|---|---|
坏了 | 9 | 0 | 0 | 0 |
油漆划痕 | 0 | 10 | 10 | 0 |
肿 | 0 | 8 | 0 | 0 |
弯曲 | 0 | 0 | 0 | 5 |
我使用了 pivot(我第一次使用它)并且我已经使用了这个:
DECLARE @StuffColumn varchar(max)
DECLARE @sql varchar(max)
DECLARE @LotId int = '1'
DECLARE @PartNumerId int = '100'
SELECT @StuffColumn = STUFF((SELECT distinct ','+QUOTENAME(SortingDate)
FROM vw_report_diarydefects
WHERE LotId = @LotId AND PartNumerId = @PartNumerId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @SQL = ' select Defect, '+ @StuffColumn +'
from
(
select SortingDate,Defect,Qty
from vw_report_diarydefects
where LotId = ''' + CONVERT(NVARCHAR(50), @LotId, 121)+ ''' and PartNumerId = ''' + CONVERT(NVARCHAR(50), @PartNumerId, 121)+ '''
)x
pivot
(
Sum(Qty)
for SortingDate in( '+@StuffColumn+' )
)p'
EXEC(@SQL)
得到这个:
缺陷 | 2019 年 10 月 1 日10:31AM | 2019 年 10 月 2 日10:31AM | 2019 年 10 月 3 日10:31AM | 2019 年 10 月 4 日10:31AM |
---|---|---|---|---|
坏了 | 空 | 空 | 空 | 空 |
油漆划痕 | 空 | 空 | 空 | 空 |
肿 | 空 | 空 | 空 | 空 |
弯曲 | 空 | 空 | 空 | 空 |
有没有办法用数量数据填充日期列?我是第一次使用 Pivot,我正在阅读该说明,但我仍有一些疑问。
尝试以下操作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication193
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("Lot",typeof(int));
dt.Columns.Add("PartNumberId",typeof(int));
dt.Columns.Add("PartNumber",typeof(string));
dt.Columns.Add("DefectId",typeof(int));
dt.Columns.Add("Defect",typeof(string));
dt.Columns.Add("Qty", typeof(int));
dt.Columns.Add("SortingDate", typeof(DateTime));
dt.Rows.Add(new object[] {1, 100, "WD40", 1, "Broken", 9, DateTime.Parse("2019-10-01 10:31:02.000")});
dt.Rows.Add(new object[] {1, 100, "WD40", 2, "Paint Scratch", 10, DateTime.Parse("2019-10-02 10:31:02.000")});
dt.Rows.Add(new object[] {1, 100, "WD40", 3, "Swollen", 8, DateTime.Parse("2019-10-02 10:31:02.000")});
dt.Rows.Add(new object[] {1, 100, "WD40", 2, "Paint Scratch", 10, DateTime.Parse("2019-10-03 10:31:02.000")});
dt.Rows.Add(new object[] {1, 100, "WD40", 4, "Bent", 5, DateTime.Parse("2019-10-04 10:31:02.000")});
DateTime[] dates = dt.AsEnumerable().Select(x => x.Field<DateTime>("SortingDate")).OrderBy(x => x).Distinct().ToArray();
DataTable pivot = new DataTable();
pivot.Columns.Add("Defect");
foreach (DateTime date in dates)
{
pivot.Columns.Add(date.ToString(), typeof(int));
}
foreach(var defect in dt.AsEnumerable().GroupBy(x => x.Field<string>("Defect")))
{
DataRow newRow = pivot.Rows.Add();
newRow["Defect"] = defect.Key;
foreach (DataRow row in defect)
{
int qty = row.Field<int>("Qty");
DateTime date = row.Field<DateTime>("SortingDate");
newRow[date.ToString()] = qty;
}
}
}
}
}
这是我的发现。 Quotename
更改日期格式的方式是问题所在。将您的 @StuffColumn 数据更改为先转换为 varchar,然后引用它。
SELECT @StuffColumn = STUFF((SELECT distinct ','+QUOTENAME(CONVERT(NVARCHAR(50),SortingDate, 121))
FROM vw_report_diarydefects
WHERE Lot = @LotId AND PartNumberId = @PartNumerId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
这是SQL Fiddle。