2016-11-30 119 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