SQL 查询以根据特定条件排除记录
SQL Query to exclude record on certain criteria
我有一种情况,我的 table 有记录,我想根据我有什么项目从中提取数据 w.r.t 组和 class。
下面是一个屏幕截图,第一部分是 table 中的记录,第二部分是我要如何提取数据。
对于 ID(s),如果我有相同的 Class 和组,但对于项目字段,在一个记录上我有 ud9 而对于其他它是空白的,那么我总是必须用项目来描绘那个。
我可以通过 select distinct ID,Class,Group,item from MyTable
where ID='A001' and item<>''
得到它
但是我还需要其他线路,请问如何获得其他线路?
并且不得获得具有相同 class 和没有项目的组的 A001 的第二行。
试试这个。
SELECT ID,
Class,
[Group],
item
FROM (SELECT Row_number()OVER(partition BY ID, Class, [Group]
ORDER BY CASE WHEN item='' THEN 1 ELSE 0 END) rn,
*
FROM MyTable)a
WHERE rn = 1
如果每个 ID
、Class
和 Group
有多个 item
,则使用此
SELECT ID,
Class,
[Group],
item
FROM (SELECT *,
CASE WHEN item = '' THEN 1 ELSE 0 END temp,
Count(1)OVER(partition BY ID, Class, [Group]) cnt
FROM MyTable)a
WHERE temp = 0
OR cnt = 1
这是解决方案之一:
DECLARE @t TABLE
(
ID CHAR(4) ,
Class CHAR(1) ,
gr CHAR(2) ,
Item CHAR(3)
)
INSERT INTO @t
VALUES ( 'A001', 'A', 'A1', 'ud9' ),
( 'A001', 'A', 'A1', '' ),
( 'A001', 'B', '', 'ud4' ),
( 'A001', 'B', '', '' ),
( 'A001', 'D', 'D2', '' ),
( 'A002', 'A', 'A1', '' );
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY ID, Class, gr ORDER BY CASE
WHEN item = ''
THEN 1
ELSE 0
END ) AS rn,
COUNT(*) OVER ( PARTITION BY ID, Class, gr) AS cn
FROM @t
)
SELECT ID, Class, gr, Item
FROM cte
WHERE rn = 1 OR cn = 1
输出:
ID Class gr Item
A001 A A1 ud9
A001 B ud4
A001 D D2
A002 A A1
您的查询将如下所示:
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY ID, Class, Group ORDER BY CASE
WHEN item = ''
THEN 1
ELSE 0
END ) AS rn,
COUNT(*) OVER ( PARTITION BY ID, Class, gr) AS cn
FROM MyTable
)
SELECT ID, Class, Group, Item
FROM cte
WHERE rn = 1 OR cn = 1
两个条件,项目为空或计数为 1,试试这个:
select distinct * from table1 t1 where item <> '' OR
(select count(*) from table1 t2 where t1.id=t2.id and
t1.class=t2.class and t1.groups=t2.groups) = 1
我有一种情况,我的 table 有记录,我想根据我有什么项目从中提取数据 w.r.t 组和 class。
下面是一个屏幕截图,第一部分是 table 中的记录,第二部分是我要如何提取数据。
对于 ID(s),如果我有相同的 Class 和组,但对于项目字段,在一个记录上我有 ud9 而对于其他它是空白的,那么我总是必须用项目来描绘那个。
我可以通过 select distinct ID,Class,Group,item from MyTable
where ID='A001' and item<>''
但是我还需要其他线路,请问如何获得其他线路? 并且不得获得具有相同 class 和没有项目的组的 A001 的第二行。
试试这个。
SELECT ID,
Class,
[Group],
item
FROM (SELECT Row_number()OVER(partition BY ID, Class, [Group]
ORDER BY CASE WHEN item='' THEN 1 ELSE 0 END) rn,
*
FROM MyTable)a
WHERE rn = 1
如果每个 ID
、Class
和 Group
有多个 item
,则使用此
SELECT ID,
Class,
[Group],
item
FROM (SELECT *,
CASE WHEN item = '' THEN 1 ELSE 0 END temp,
Count(1)OVER(partition BY ID, Class, [Group]) cnt
FROM MyTable)a
WHERE temp = 0
OR cnt = 1
这是解决方案之一:
DECLARE @t TABLE
(
ID CHAR(4) ,
Class CHAR(1) ,
gr CHAR(2) ,
Item CHAR(3)
)
INSERT INTO @t
VALUES ( 'A001', 'A', 'A1', 'ud9' ),
( 'A001', 'A', 'A1', '' ),
( 'A001', 'B', '', 'ud4' ),
( 'A001', 'B', '', '' ),
( 'A001', 'D', 'D2', '' ),
( 'A002', 'A', 'A1', '' );
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY ID, Class, gr ORDER BY CASE
WHEN item = ''
THEN 1
ELSE 0
END ) AS rn,
COUNT(*) OVER ( PARTITION BY ID, Class, gr) AS cn
FROM @t
)
SELECT ID, Class, gr, Item
FROM cte
WHERE rn = 1 OR cn = 1
输出:
ID Class gr Item
A001 A A1 ud9
A001 B ud4
A001 D D2
A002 A A1
您的查询将如下所示:
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY ID, Class, Group ORDER BY CASE
WHEN item = ''
THEN 1
ELSE 0
END ) AS rn,
COUNT(*) OVER ( PARTITION BY ID, Class, gr) AS cn
FROM MyTable
)
SELECT ID, Class, Group, Item
FROM cte
WHERE rn = 1 OR cn = 1
两个条件,项目为空或计数为 1,试试这个:
select distinct * from table1 t1 where item <> '' OR
(select count(*) from table1 t2 where t1.id=t2.id and
t1.class=t2.class and t1.groups=t2.groups) = 1