可能是一个愚蠢的例子,但很想知道如何使用SQL查询来做到这一点。我正在使用MySQL但尝试编写查询db独立方式。
我有下表,
Course
---------
Id | lang | batch | flag
===========================
1 | Java | A | null
2 | Cpp | B | null
3 | Java | A | null
4 | Java | C | null
5 | Java | C | null
查询是,如果为同一批次找到lang = Java的两条记录,则为第一个条目设置flag = 0,为表格中的第二个条目设置flag = 1。
因此上述查询的输出如下所示,
Course
---------
Id | lang | batch | flag
===========================
1 | Java | A | 0
2 | Cpp | B | null
3 | Java | A | 1
4 | Java | C | 0
5 | Java | C | 1
我如何为上面的例子编写SQL查询。感谢您的帮助:)
编辑: 对于晚期编辑,很抱歉,如果只找到一条lang = java和任何批处理的记录,那么将标志设置为0。 是否可以在单个查询中编写两个查询?
答案 0 :(得分:2)
假设给定的匹配批次只有两个记录,以下内容应该可以正常工作:
UPDATE Course t1
INNER JOIN
(
SELECT batch
FROM Course
GROUP BY batch
HAVING SUM(CASE WHEN lang = 'Java' THEN 1 ELSE 0 END) = 2
) t2
ON t1.batch = t2.batch
INNER JOIN
(
SELECT batch, MIN(Id) AS minId
FROM Course
GROUP BY batch
) t3
ON t2.batch = t3.batch
SET t1.flag = CASE WHEN t1.Id = t3.minId THEN 0 ELSE 1 END
在这里演示:
注意:上面的Fiddle执行SELECT
来显示哪些记录将被更新,以及每个记录的旧标志值和新标志值。
您需要使用的确切JOIN
语法是特定于数据库的。我给出了MySQL的语法,但是只要它支持连接更新,查询在转到另一个RDBMS(如SQL Server)时不会有太大变化。
答案 1 :(得分:1)
使用CTE创建行号并根据CTE更新物理表:
CREATE TABLE #Course(Id INT,lang VARCHAR(100), batch VARCHAR(10),flag INT)
INSERT INTO #Course(Id ,lang , batch ,flag )
SELECT 1 ,'Java','A' , NULL UNION ALL
SELECT 2 ,'Cpp','B' , NULL UNION ALL
SELECT 3 ,'Java','A' , NULL UNION ALL
SELECT 4 ,'Java','C' , NULL UNION ALL
SELECT 5 ,'Java','C' , NULL
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY batch ORDER BY Id) RNo , lang
,batch,Id FROM #Course
)
UPDATE #Course SET flag = CASE WHEN RNo = 1 THEN 0 ELSE 1 END
FROM CTE
WHERE #Course.Id = CTE.Id
SELECT * FROM #Course
答案 2 :(得分:0)
有2个更新:
首先:
update Course set flag = 0 where Id in (select min(id) from Course C where
Lang = 'Java' group by lang, batch);
第二
update Course set flag = 1 where lang = 'Java' and flag is null
答案 3 :(得分:0)
我认为我们可以通过使用CASE和子查询来实现:
update c set c.flag = case when c.id = t.id then 1 else 0 end
from #Course c
inner join (select max(id) id, lang, batch
from #Course
group by lang, batch having count(id)>1) t on c.lang = t.lang
and t.batch = c.batch
答案 4 :(得分:0)
这是PostgreSQL测试版本:
UPDATE
Course
SET
flag = CASE WHEN t2.min = Course.Id THEN 0 ELSE 1 END
FROM
(SELECT
Course.batch,
MIN(Course.Id)
FROM
Course
WHERE
Course.lang = 'Java'
GROUP BY
Course.batch
HAVING COUNT(Course.batch) = 2) AS t2
WHERE
Course.batch = t2.batch