[英]Combine two SQL queries?
我有两个表Table_1
和Table_2
。
我正在使用此SQL语句计算表Info_Data
中的Table_1
列中特定数据出现了多少次。 以其当前的硬编码形式,它返回的值为9
SELECT Staff_No, Info_Data, COUNT(*) cCount
FROM Staff_Manager.dbo.Staff_Time_TBL
WHERE Staff_No = 3201 AND Date_Data BETWEEN '2016/6/1' AND '2016/7/1' AND Info_Data = 'Data_1'
GROUP BY Staff_No, Info_Data
然后,我还有另一个SQL语句,用于检查Table_2
中是否存在Table_2
,如果不存在,则插入一行并更新数据。 如果确实如此,则只需更新数据即可。
IF EXISTS (SELECT * FROM Staff_Manager.dbo.Staff_Count_TBL WHERE Staff_No = 3201 AND Year_D = 2016 AND Month_D = 6 AND Column_Index = 1)
BEGIN
UPDATE Staff_Manager.dbo.Staff_Count_TBL
SET Column_Value = 9
WHERE Staff_No = 3201 AND Year_D = 2016 AND Month_D = 6 AND Column_Index = 1
END
ELSE
BEGIN
INSERT INTO Staff_Manager.dbo.Staff_Count_TBL (Staff_No, Year_D, Month_D, Column_Index, Column_Value)
VALUES (3201, 2016, 6, 1, 9)
END
这两个语句都按预期工作。
但是我找不到结合这两个语句的方法,我尝试了JOIN
, MERGE
没有运气。 作为在第一语句返回的值9
,我想更换硬编码9
在这条线上SET Column_Value = 9
和Column_Value
列值9
在这条线VALUES (3201, 2016, 6, 1, 9)
与结果第一个陈述
这显然是不正确的,但这只是为了说明我正在尝试做的事情。
IF EXISTS (SELECT * FROM Staff_Manager.dbo.Staff_Count_TBL WHERE Staff_No = 3201 AND Year_D = 2016 AND Month_D = 6 AND Column_Index = 1)
BEGIN
UPDATE Staff_Manager.dbo.Staff_Count_TBL
SET Column_Value = SELECT Staff_No, Info_Data, COUNT(*) cCount
FROM Staff_Manager.dbo.Staff_Time_TBL
WHERE Staff_No = 3201 AND Date_Data BETWEEN '2016/6/1' AND '2016/7/1' AND Info_Data = 'Data_1'
GROUP BY Staff_No, Info_Data
WHERE Staff_No = 3201 AND Year_D = 2016 AND Month_D = 6 AND Column_Index = 1
END
ELSE
BEGIN
INSERT INTO Staff_Manager.dbo.Staff_Count_TBL (Staff_No, Year_D, Month_D, Column_Index, Column_Value)
VALUES (3201, 2016, 6, 1, SELECT Staff_No, Info_Data, COUNT(*) cCount
FROM Staff_Manager.dbo.Staff_Time_TBL
WHERE Staff_No = 3201 AND Date_Data BETWEEN '2016/6/1' AND '2016/7/1' AND Info_Data = 'Data_1'
GROUP BY Staff_No, Info_Data)
END
您的第一个查询将返回多个列,并且您不能使用它来更新或插入单个列。 相反,使其仅返回count()
并尝试
UPDATE Staff_Manager.dbo.Staff_Count_TBL
SET Column_Value = (
SELECT COUNT(*)
FROM Staff_Manager.dbo.Staff_Time_TBL
WHERE Staff_No = 3201 AND Date_Data BETWEEN '2016/6/1' AND '2016/7/1' AND Info_Data = 'Data_1'
GROUP BY Staff_No, Info_Data
)
WHERE Staff_No = 3201 AND Year_D = 2016 AND Month_D = 6 AND Column_Index = 1
和
INSERT INTO Staff_Manager.dbo.Staff_Count_TBL
(Staff_No, Year_D, Month_D, Column_Index, Column_Value)
SELECT 3201, 2016, 6, 1, COUNT(*)
FROM Staff_Manager.dbo.Staff_Time_TBL
WHERE Staff_No = 3201 AND Date_Data BETWEEN '2016/6/1' AND '2016/7/1' AND Info_Data = 'Data_1'
GROUP BY Staff_No, Info_Data
如您所见,在INSERT中没有VALUES构造,请阅读http://www.w3schools.com/sql/sql_insert_into_select.asp了解更多详细信息。 另请参阅如何从SQL Server中的SELECT更新? 。
PS单个查询不需要使用BEGIN / END,可以跳过它们。
接受的答案中的两个语句中的冗余使我感到困扰,即对一个业务规则的更改将需要至少在两个位置进行更改。
因此,这是我尝试编写等效的MERGE
语句的尝试(相信您可以在这里看到表值参数的潜力):
WITH Params AS
(
SELECT *
FROM ( VALUES ( 3201, 2016, 6, 1 ) )
AS T ( Staff_No, Year_D, Month_D, Column_Index )
),
ParamsWithCount AS
(
SELECT p.Staff_No, p.Year_D, p.Month_D, p.Column_Index, COUNT(*) AS Column_Value
FROM Params p
JOIN Staff_Manager.dbo.Staff_Time_TBL t
ON p.Staff_No = t.Staff_No
WHERE t.Date_Data BETWEEN '2016/6/1' AND '2016/7/1'
AND t.Info_Data = 'Data_1'
GROUP
BY p.Staff_No, p.Year_D, p.Month_D, p.Column_Index, t.Info_Data
)
MERGE Staff_Manager.dbo.Staff_Count_TBL t
USING ParamsWithCount p
ON t.Staff_No = p.Staff_No
AND t.Year_D = p.Year_D
AND t.Month_D = p.Month_D
AND t.Column_Index = p.Column_Index
WHEN MATCHED THEN
UPDATE
SET Column_Value = p.Column_Value
WHEN NOT MATCHED THEN
INSERT ( Staff_No, Year_D, Month_D, Column_Index, Column_Value )
VALUES ( p.Staff_No, p.Year_D, p.Month_D, p.Column_Index, p.Column_Value );
我也不禁怀疑Date_Data BETWEEN '2016/6/1' AND '2016/7/1'
的硬编码逻辑实际上是否与参数值Year_D = 2016 AND Month_D = 6
。
可以将其制成具有表值参数的proc来代替上方的params
CTE,例如:
CREATE TYPE Staff_Count_Type AS TABLE
(
Staff_No INT,
Year_D INT,
Month_D INT,
Column_Index INT
);
CREATE PROCEDURE UpateOrCreateStaffCount
@params Staff_Count_Type READONLY
AS
WITH ParamsWithCount AS
(
SELECT p.Staff_No, p.Year_D, p.Month_D, p.Column_Index, COUNT(*) AS Column_Value
FROM @params p
JOIN Staff_Manager.dbo.Staff_Time_TBL ...snipped...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.