我有3个表格,分别是class,Student和Religion,以下数据如下
分类表
ClassId ClassName
1 class-1
2 class-2
3 class-3
宗教信仰表
ReligionId RegionName
1 Hindu
2 Muslim
学生桌
employeeid StudentName religionid dateofbirth classid
1 A 1 1990-12-04 1
2 B 2 1999-12-04 2
3 C 2 2000-12-04 1
4 D 2 1988-12-04 1
5 E 2 2003-12-04 2
6 F NULL 2002-12-04 1
如何从上表获得以下记录
CLASSNAME HINDU MUSLIM Noreligion
class-1 1 2 1
class-2 0 2 0
您可以使用以下脚本创建表格
CREATE TABLE [dbo].[class](
[ClassId] [int] IDENTITY(1,1) NOT NULL,
[ClassName] [varchar](250) NULL,
CONSTRAINT [PK_class] PRIMARY KEY CLUSTERED
(
[ClassId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Religion](
[ReligionId] [int] NOT NULL,
[RegionName] [varchar](50) NULL,
CONSTRAINT [PK_Religion] PRIMARY KEY CLUSTERED
(
[ReligionId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Student](
[employeeid] [int] IDENTITY(1,1) NOT NULL,
[StudentName] [varchar](150) NULL,
[religionid] [int] NULL,
[dateofbirth] [date] NULL,
[classid] [int] NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[employeeid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[class] ON
INSERT [dbo].[class] ([ClassId], [ClassName]) VALUES (1, N'class-1')
INSERT [dbo].[class] ([ClassId], [ClassName]) VALUES (2, N'class-2')
INSERT [dbo].[class] ([ClassId], [ClassName]) VALUES (3, N'class-3')
SET IDENTITY_INSERT [dbo].[class] OFF
INSERT [dbo].[Religion] ([ReligionId], [RegionName]) VALUES (1, N'hindu')
INSERT [dbo].[Religion] ([ReligionId], [RegionName]) VALUES (2, N'muslim')
SET IDENTITY_INSERT [dbo].[Student] ON
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (1, N'A', 1, CAST(N'1990-12-04' AS Date), 1)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (2, N'B', 2, CAST(N'1999-12-04' AS Date), 2)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (3, N'C', 2, CAST(N'2000-12-04' AS Date), 1)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (4, N'D', 2, CAST(N'1988-12-04' AS Date), 1)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (5, N'E', 2, CAST(N'2003-12-04' AS Date), 2)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (6, N'F', NULL, CAST(N'2002-12-04' AS Date), 1)
SET IDENTITY_INSERT [dbo].[Student] OFF
是否要求使用数据透视表。 我无法使查询获得此类记录。
答案 0 :(得分:1)
这是更关键的条件聚合。这样可以为您带来想要的结果:
SELECT C.ClassName,
COUNT(CASE R.RegionName WHEN 'Hindu' THEN 1 END) AS Hindu,
COUNT(CASE R.RegionName WHEN 'Muslim' THEN 1 END) AS Muslim,
COUNT(CASE WHEN R.RegionName IS NULL THEN 1 END) AS NoReligion
FROM dbo.class C
JOIN dbo.Student S ON C.ClassId = S.classid
LEFT JOIN dbo.Religion R ON S.religionid = R.ReligionId
GROUP BY C.ClassName;
如果您不懂语法,请询问。
编辑:OP现在已经指出,除了所提供的两种宗教之外,还有更多的宗教,并且需要保持动态。因此,得出:
--Additional sample row if you wish:
INSERT [dbo].[Religion] ([ReligionId], [RegionName])
VALUES (3, N'Catholic');
GO
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT C.ClassName,' + NCHAR(10) +
STUFF((SELECT N',' + NCHAR(10) +
N' COUNT(CASE R.RegionName WHEN ' + QUOTENAME(R.RegionName,N'''') + N' THEN 1 END) AS ' + QUOTENAME(R.RegionName)
FROM dbo.Religion R
ORDER BY R.ReligionId
FOR XML PATH(N'')),1,2,N'') + N',' + NCHAR(10) +
N'COUNT(CASE WHEN R.RegionName IS NULL THEN 1 END) AS NoReligion' + NCHAR(10) +
N'FROM dbo.class C' + NCHAR(10) +
N' JOIN dbo.Student S ON C.ClassId = S.classid' + NCHAR(10) +
N' LEFT JOIN dbo.Religion R ON S.religionid = R.ReligionId' + NCHAR(10) +
N'GROUP BY C.ClassName;';
SELECT @SQL;
EXEC sp_executesql @SQL;
答案 1 :(得分:1)
这是带有动态列的数据透视表。您的宗教信仰数目不详
// Using native promises:
const calculateExpense = function (proName) {
return fetch('/purchase')
.then((response) => {
if (response.status >= 400) { throw new Error(response.status.toString()); }
const result = response.json();
let totalExpense = 0;
let totalQuantity = 0;
for (let purchase of result) {
if (proName === purchase.productName) {
totalExpense += purchase.totalPrice;
totalQuantity += purchase.purchasedQuantity;
}
}
return totalExpense / totalQuantity;
});
};
// Using async/await:
const calculateExpense = async function (proName) {
const response = await fetch('/purchase');
if (response.status >= 400) { throw new Error(response.status.toString()); }
const result = response.json();
let totalExpense = 0;
let totalQuantity = 0;
for (let purchase of result) {
if (proName === purchase.productName) {
totalExpense += purchase.totalPrice;
totalQuantity += purchase.purchasedQuantity;
}
}
return totalExpense / totalQuantity;
};
calculateExpense('name')
.then((expensePerProduct) => {
// TODO: do something.
})
.catch(err => console.log(`Error: ${err}`));