簡體   English   中英

SQL查詢更新表

[英]SQL query to update table

可能是愚蠢的示例,但好奇地知道如何使用SQL查詢來實現。 我正在使用MySQL,但嘗試以獨立的方式編寫查詢數據庫。

我有下表

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的兩個記錄且批次相同,則在表中為第一項設置標志= 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查詢。 感謝幫助 :)

編輯:對不起,對於后期編輯,還有一個附加功能,例如,如果僅找到lang = java的一條記錄,然后將任何批次的標志設置為0,是否可以在單個查詢中寫入兩個查詢?

假設給定的匹配批處理只有兩個記錄,則以下內容應能正常工作:

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的聯接更新,查詢就不會發生太大變化。

使用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個更新:

第一:

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

我認為我們可以通過在子查詢中使用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

這是經過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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM