我有一个ASP.Net Sql Server 2012应用程序,我正在尝试使用SQL从四个表创建一个报告。我在获取一个字段(状态)字段的数据时遇到问题。
我有四张桌子:
我想要做的是创建一个这样的报告,它显示了在AdminTest和UserTest表中有一个antry的测试ABC和只在AdminTest表中有一个条目的测试DEF:
Code PurchaseDate Questions Status
ABC 2012/1/1 50 Available
DEF 25 Purchase Now
最初只有AdminTest行,没有可用于加入的UserTest。使用LEFT OUTER JOIN可以正常处理。当用户购买测试时,购买日期将有一个条目,我将能够加入UserTest和UserTestStatus列。
如果没有用户测试,那么我希望状态设置为“立即购买”
这是我到目前为止所拥有的。它仅适用于特定测试代码的AdminTest和UserTest表。
SELECT AdminTest.Code AS Code,
UserTest.PurchaseDate AS PurchaseDate,
COUNT(AdminTestQuestion.AdminTestQuestionId) AS Questions,
UserTestStatus.Name AS Status
FROM AdminTest LEFT OUTER JOIN UserTest ON AdminTest.AdminTestId = UserTest.AdminTestId
AND UserTest.UserId = @UserId
JOIN AdminTestQuestion ON AdminTest.AdminTestId = AdminTestQuestion.AdminTestId
AND AdminTest.ExamId = @ExamId
AND AdminTest.TestStatusId = 3
JOIN UserTestStatus ON UserTest.TestStatusId = UserTestStatus.UserTestStatusId
GROUP BY AdminTest.Code,
UserTest.PurchaseDate,
UserTestStatus.Name
所以连接需要看起来像这样:
AdminTest >>> AdminTestQuestions
>>> UserTest (optional) >>> UserTestStatus
有人可以给我一些建议,告诉我如何让状态的数据等于单词“Purchase Now
”,或者如果有UserTest
那么就是实际状态已被购买。
更新:
这是一个提出的答案。我包括了这个以及下面三个选项的输出。我希望这有助于显示数据。我可以在这里添加任何其他内容,以便在需要时显示更多数据。
选择1:
SELECT Code, AdminTestId
FROM AdminTest
输出
Code AdminTestId
abcdef 131
ddddddd 1130
选择2:
SELECT AdminTestId, UserTestId
FROM UserTest
输出
AdminTestId UserTestId
131 202
选择3:
SELECT AdminTestQuestionId, AdmintestId, QuestionUId
FROM AdminTestQuestion
输出
3094 131 3CEFF956-BF61-419E-8FB2-9D6A1B75B909
4094 1130 5D679FAD-2904-45A1-AA5F-3DB16850438D
4095 1130 96EA8351-FA2B-4DB3-862D-260CA085563A
选择4:
SELECT *
FROM UserTestStatus
输出:
0 Available
1 Started
2 Paused
3 Finished
4 Marked
解决方案:
SELECT temp.Code,
temp.Questions,
UserTest.PurchaseDate AS PurchaseDate,
(CASE
WHEN UserTestStatus.Name IS NULL THEN 'Purchase Now'
ELSE UserTestStatus.Name
END) AS Status
FROM
(SELECT AdminTest.Code AS Code,
AdminTest.AdminTestId,
COUNT(AdminTestQuestion.AdminTestQuestionId) AS Questions
FROM AdminTest
JOIN AdminTestQuestion ON AdminTest.AdminTestId = AdminTestQuestion.AdminTestId
AND AdminTest.TestStatusId = 3
GROUP BY AdminTest.Code, AdminTest.AdminTestId) temp
LEFT OUTER JOIN UserTest ON temp.AdminTestId = UserTest.AdminTestId
LEFT OUTER JOIN UserTestStatus ON UserTest.TestStatusId = UserTestStatus.UserTestStatusId
以下是我需要看到的内容:
Code PurchaseDate Questions Status
abcdef 2014-10-17 15:27:31.760 1 Available
ddddddd null 1 Purchase Now
答案 0 :(得分:4)
仅当有一个AdminTest和UserTest表时,它才有效 特别测试代码。
发生这种情况的原因是因为您的加入条件UserTest.UserId = @UserId
限制了结果在UserTest中有UserId
的连接发生。这需要更改为AdminTest.UserId = @UserId
。在这里,我假设您将UserId
存储在AdminTest
中,UserTest
只有用户购买的条目
如果没有用户测试,那么我希望设置状态 “立即购买”
为此,您需要使用CASE声明
CASE
WHEN UserTestStatus.Name IS NULL THEN 'Purchase Now'
ELSE UserTestStatus.Name
END
更新 :(基于OP对问题的更新)
原始查询中的另一个错误是使用导致当前输出的GROUP BY
PurchaseDate
和UserTestStatus
。
因此,您的最终查询将是
SELECT temp.Code,
temp.Questions,
UserTest.PurchaseDate AS PurchaseDate,
(CASE
WHEN UserTestStatus.Name IS NULL THEN 'Purchase Now'
ELSE UserTestStatus.Name
END) AS Status
FROM
(SELECT AdminTest.Code AS Code,
AdminTest.AdminTestId,
COUNT(AdminTestQuestion.AdminTestQuestionId) AS Questions,
FROM AdminTest
JOIN AdminTestQuestion ON AdminTest.AdminTestId = AdminTestQuestion.AdminTestId
AND AdminTest.TestStatusId = 3
GROUP BY AdminTest.Code) temp
LEFT OUTER JOIN UserTest ON temp.AdminTestId = UserTest.AdminTestId
LEFT OUTER JOIN UserTestStatus ON UserTest.TestStatusId = UserTestStatus.UserTestStatusId