2016-11-30 95 views
2

可能是一个愚蠢的例子,但很想知道我们如何使用SQL查询来做到这一点。我正在使用MySQL,但试图以独立的方式编写查询数据库。SQL查询更新表

我有下表,

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 

查询,如果发现郎=爪哇与同一批次然后设置标志= 0为用于表第二条目的第一个条目,并设置标志= 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查询。感谢您的帮助:)

编辑: 对不起迟到编辑,有一个像另外如果只有找到了郎= java和任何批次然后设置标志为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 

演示在这里:

SQLFiddle

注:以上小提琴做了SELECT显示哪些记录将被更新,以及每个记录的新旧标记值是多少。

确实需要使用的JOIN语法是数据库特定的。我给出了MySQL的语法,但只要它支持连接更新,查询在转到另一个RDBMS(如SQL Server)时不应发生太大变化。

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 
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 
0

我想我们可以d通过使用与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 
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