我希望有两个存储过程可以匹配'并且'无与伦比的'行,分别......来自单个表......
'匹配'行是两行,状态分别为1和2,相同:
uID aID cID and pID
无与伦比的' row是一个状态为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
答案 0 :(得分:2)
假设uID, aID, cID, pID
的每个唯一耦合只会在这些状态中一次,您可以使用它。
--matching rows
select t.*
from table t
inner join
(select uID, aID, ,cID, pID
from table
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
--unmatching rows
select t.*
from table t
inner join
(select uID, aID, ,cID, pID
from table
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
答案 1 :(得分:1)
我能够使用exists
和not exists
--Matched row code
SELECT *
FROM Data D1
WHERE EXISTS (SELECT *
FROM Data D2
WHERE D2.uID = D1.uID AND D2.aID = D1.aID AND D2.cID = D1.cID
AND D2.state = 2)
ORDER BY uID, state
--Unmatched row code
SELECT *
FROM Data D1
WHERE NOT EXISTS (SELECT *
FROM Data D2
WHERE D2.uID = D1.uID AND D2.aID = D1.aID AND D2.cID = D1.cID
AND D2.state = 2)
ORDER BY uID, state
答案 2 :(得分:1)
这个怎么样?我假设这里只有2个状态1和2。
SELECT a.*
FROM Data a
JOIN (SELECT uID, aID, cID, pID, Count(*) as NumMatches
FROM Data
Group By uID, aID, cID, pID
Having Count(*) = 2) b ON a.uID = b.uID and a.aID = b.aID and a.cID = b.cID and a.pID = b.pID
Order by a.uID, a.aID, a.cID, a.pID
和非匹配
SELECT a.*
FROM Data a
LEFT OUTER JOIN (SELECT uID, aID, cID, pID, Count(*) as NumMatches
FROM Data
Group By uID, aID, cID, pID
Having Count(*) = 2) b ON a.uID = b.uID and a.aID = b.aID and a.cID = b.cID and a.pID = b.pID
WHERE IsNull(b.uID,0) = 0
Order by a.uID, a.aID, a.cID, a.pID