【发布时间】:2018-04-18 03:18:37
【问题描述】:
我想让两个存储过程分别从一个表中获取“匹配”和“不匹配”行...
“匹配”行是状态分别为 1 和 2 的两行,对于相同的:
uID aID cID and pID
“不匹配”行是状态为 1 的行,但不存在状态为 2 且具有相同 uID、aID、cID 和 pID 的行
(为简洁起见,我从数据中删除了唯一标识符 Indx)
样本数据
uID aID cID pID state occurs
10 200 5000 1240 1 2018-04-17 08:12:13.367
80 542 9000 5700 1 2018-04-17 08:12:54.113
10 240 5000 3860 1 2018-04-17 08:13:09.817
10 200 5000 1240 2 2018-04-17 08:13:18.010
30 240 7000 5938 1 2018-04-17 08:13:31.510
80 542 9000 5700 2 2018-04-17 08:14:04.363
以下是“匹配”行的示例
uID aID cID pID state occurs
10 200 5000 1240 1 2018-04-17 08:12:13.367
10 200 5000 1240 2 2018-04-17 08:13:18.010
80 542 9000 5700 1 2018-04-17 08:12:54.113
80 542 9000 5700 2 2018-04-17 08:14:04.363
以下是“不匹配”行的示例
uID aID cID pID state occurs
10 240 5000 3860 1 2018-04-17 08:13:09.817
30 240 7000 5938 1 2018-04-17 08:13:31.510
匹配的行代码
我遇到困难的地方是围绕将匹配集分组的语句......我想我可以做这样的事情来获得1和2的两行但没有这样的运气......
select uID, aID, cID, pID, state
from Data where state in (1,2)
group by uID, aID, cID, pID, state
having state = 2 and state = 1
不匹配的行代码
然后我想我可以对不匹配的行做类似的事情,但这也不起作用....
select uID, aID, cID, pID, state
from Data where state in (1,2)
group by uID, aID, cID, pID, state
having state != 2 and state = 1
我需要一些帮助...谢谢
基础设施
创建表格的代码如下:
CREATE TABLE [dbo].[Data](
[INDX] [uniqueidentifier] NOT NULL,
[uID] [int] NOT NULL,
[aID] [int] NOT NULL,
[cID] [int] NOT NULL,
[pID] [int] NOT NULL,
[state] [int] NOT NULL,
[occurs] [datetime] NOT NULL,
CONSTRAINT [PK_Data] PRIMARY KEY CLUSTERED
(
[INDX] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
“插入数据”的存储过程
CREATE PROCEDURE [dbo].[InsertData]
-- Add the parameters for the stored procedure here
@userID int,
@appID int,
@compID int,
@procID int,
@state int,
@occurence datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
declare @indx as uniqueidentifier
set @indx = NEWID();
insert into [Data]
Values(
@indx,
@userID,
@appID,
@compID,
@procID,
@state,
@occurence
)
END
GO
这里有一些代码可以帮助填充表格:
declare @userID int
declare @appID int
declare @compID int
declare @procID int
declare @state int
declare @occurence datetime
set @userID = 10
set @appID = 200
set @compID = 5000
set @procID = 1240
set @state = 1
set @occurence = GETDATE();
EXEC InsertData @userID, @appID, @compID, @procID, @state, @occurence
添加其他状态时进行测试:
set @userID = 80
set @appID = 546
set @compID = 9000
set @procID = 5700
set @state = 3
set @occurence = GETDATE();
EXEC InsertData @userID, @appID, @compID, @procID, @state, @occurence
所以我最终得到了这个数据集:
uID aID cID pID state
10 200 5000 1240 2
10 200 5000 1240 1
10 240 5000 3860 1
80 542 9000 5700 1
30 240 7000 5938 1
80 546 9000 5700 3
80 542 9000 5700 2
所以...scsimon...您的查询效果很好...但是如果是这种情况怎么办:
添加了新的重复数据
uID aID cID pID state
10 200 5000 1240 1
80 542 9000 5700 1
10 240 5000 3860 1
10 200 5000 1240 2
30 240 7000 5938 1
80 542 9000 5700 2
80 546 9000 4502 3
10 200 5000 1240 1
10 200 5000 1240 2
查询结果,接近了……
uID aID cID pID state occurs
10 200 5000 1240 1 2018-04-17 11:57:22.693
10 200 5000 1240 1 2018-04-17 11:57:29.797
10 200 5000 1240 2 2018-04-17 11:57:25.740
10 200 5000 1240 2 2018-04-17 11:57:30.827
80 542 9000 5700 1 2018-04-17 11:57:23.710
80 542 9000 5700 2 2018-04-17 11:57:27.767
但我真正想要的是:
uID aID cID pID state occurs
10 200 5000 1240 1 2018-04-17 11:57:22.693
10 200 5000 1240 2 2018-04-17 11:57:25.740
10 200 5000 1240 1 2018-04-17 11:57:29.797
10 200 5000 1240 2 2018-04-17 11:57:30.827
80 542 9000 5700 1 2018-04-17 11:57:23.710
80 542 9000 5700 2 2018-04-17 11:57:27.767
最终答案(感谢 scsimon)
'匹配'
select t.uID, t.aID, t.cID, t.pID, t.state, t.occurs
from Data t
inner join
(select uID, aID, cID, pID
from Data
where state in (1,2) --optional if needed
group by uID, aID, cID, pID
having count(*) > 1) t2 on
t2.uID = t.uID
and t2.aID = t.aID
and t2.cID = t.cID
and t2.pID = t.pID
order by uID, occurs, state
返回一组:
uID aID cID pID state occurs
10 200 5000 1240 1 2018-04-17 11:57:22.693
10 200 5000 1240 2 2018-04-17 11:57:25.740
10 200 5000 1240 1 2018-04-17 11:57:29.797
10 200 5000 1240 2 2018-04-17 11:57:30.827
80 542 9000 5700 1 2018-04-17 11:57:23.710
80 542 9000 5700 2 2018-04-17 11:57:27.767
'不匹配'
select t.uID, t.aID, t.cID, t.pID, t.state, t.occurs
from Data t
inner join
(select uID, aID, cID, pID
from Data
where state in (1,2) --optional if needed
group by uID, aID, cID, pID
having count(*) = 1) t2 on
t2.uID = t.uID
and t2.aID = t.aID
and t2.cID = t.cID
and t2.pID = t.pID
order by occurs
返回一个集合:
uID aID cID pID state occurs
10 240 5000 3860 1 2018-04-17 11:57:24.727
30 240 7000 5938 1 2018-04-17 11:57:26.753
【问题讨论】:
-
在这里想想你的 where 谓词。您要求 state = 1 AND state = 2 的行。单行不能有超过 1 个值,因此这将永远不会返回任何行。但是由于您将它们分组,您可以使用 count(*) = 2 来获得两者。并且不确定你在用 2 和 = 1 做什么。这很奇怪。
标签: sql-server stored-procedures