我有一个测验表
id | user_id | quiz_id
--------------------------
1 | 34567 | 12334
2 | 34567 | 12334
3 | 34567 | 23455
id 1和2描述了一个可以分配给同一个用户两次的测验
和一个测验交易表
id | date | status
------------------------
1 | 2014 | assigned
2 | 2014 | assigned
3 | 2014 | assigned
------------------------
1 | 2014 | completed
id
是测验表id的外键,最后一行描述用户完成测验时,事务表中的行更新状态为'completed'
预期结果:我想要一个像
这样的结构的表id | user_id| course_id | date | status
------------------------------------------
1 | 34567 | 12334 | 2014 | completed
2 | 32567 | 12334 | 2014 | assigned
3 | 2014 | 23455 | 2014 | assigned
我的查询是
SELECT q.id, q.user_id, q.course_id, qt.date, qt.status FROM quiz q
LEFT JOIN
quiz_transaction qt ON
q.id = qt.id
但它给了我额外的行(如查询所示)
1 | 34567 | 12334 | 2014 | assigned
我无法使用
ON qt.type = 'completed'
因为如果它完成了它应该返回一个已完成的行,如果不是,它应该返回一个指定的行,但不能返回两者。
所以在结果中我不能拥有
1 | 34567 | 12334 | 2014 | completed
1 | 34567 | 12334 | 2014 | assigned
我该怎么做?
答案 0 :(得分:1)
如何简单地将MAX()
功能与GROUP BY
(SQL Fiddle)一起使用:
SELECT q.id, q.user_id, q.course_id, qt.date, MAX(qt.status) AS Status
FROM quiz q
LEFT JOIN quiz_transaction qt ON q.id = qt.id
GROUP BY q.id, q.user_id, q.course_id, qt.date
编辑:如果您需要以某种方式订购字符串,可以使用CASE语句将字符串转换为数字。获取MAX值,然后将其转换回来(SQL Fiddle):
SELECT m.id, m.user_id, m.quiz_id, MAX(m.date),
CASE WHEN MAX(m.status) = 1 THEN 'assigned'
WHEN MAX(m.status) = 2 THEN 'doing'
WHEN MAX(m.status) = 3 THEN 'completed' END AS Status
FROM
(
SELECT q.id, q.user_id, q.quiz_id, qt.date,
CASE WHEN qt.status = 'assigned' THEN 1
WHEN qt.status = 'doing' THEN 2
WHEN qt.status = 'completed' THEN 3 END AS Status
FROM quiz q
LEFT JOIN quiz_transaction qt ON q.id = qt.id
) AS m
GROUP BY m.id, m.user_id, m.quiz_id;
答案 1 :(得分:1)
根据您的版本,SQLnServer支持标准SQL的“窗口聚合函数”。 ROW_NUMBER将为您提供一行:
SELECT
q.id
,q.user_id
,q.quiz_id
,qt.date
,qt.status
FROM quiz q
JOIN
(
SELECT
id
,date
,status
,ROW_NUMBER()
OVER (PARTITION BY id
ORDER BY Status DESC) as rn
FROM quiz_transaction
) as qt
ON q.id = qt.id
WHERE rn = 1
如果你有更复杂的订购规则,你需要使用CASE:
,ROW_NUMBER()
OVER (PARTITION BY id
ORDER BY CASE Status WHEN 'completed' THEN 1
WHEN 'doing' THEN 2
WHEN 'assigned' THEN 3
END) as rn
答案 2 :(得分:0)
试试这个
SELECT q.id, q.user_id, q.course_id, q1.date, qt.status FROM quiz q
LEFT JOIN
(Select id , convert(varchar,max(convert(varbinary,status ))) 'Status'
from quiz_transaction
group by id
) qt ON
q.id = qt.id
left join quiz_transaction q1 on q1.id = qt.id and q1.status=qt.status