這是我正在使用的架構和資料
CREATE TABLE tbl (
name varchar(20) not null,
groups int NOT NULL
);
insert into tbl values('a', 35);
insert into tbl values('a', 36);
insert into tbl values('b', 35);
insert into tbl values('c', 36);
insert into tbl values('d', 37);
| name | groups|
|------|-------|
| a | 35 |
| a | 36 |
| b | 35 |
| c | 36 |
| d | 37 |
現在我只需要那些具有大于或等于 35 的組的名稱,但另外一個是當也存在相應的組 = 36 時,我只能包含組 = 35 的行
| name | groups|
|------|-------|
| a | 35 |
| a | 36 |
第二個條件是它可以包括那些具有大于或等于 36 的組而沒有組 = 35 的名稱
| name | groups|
|------|-------|
| c | 36 |
| d | 37 |
它應該排除的唯一情況是記錄只有組= 35 沒有相應的組= 36
| name | groups|
|------|-------|
| b | 35 |
我試過以下
select name from tbl
where groups>=35
group by name
having count(distinct(groups))>=2
or groups>=36;
這是我面臨的錯誤 Column 'tbl.groups' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
uj5u.com熱心網友回復:
因此,據我所知,您只想限制 35 組本身的位置。我想,讓我們嘗試隔離那些只有組 = 35 然后不存在的名稱。這是您追求的正確輸出嗎?
此外,在 where 子句中使用復雜的 OR 通常會導致您的查詢不是 SARGable。最好使用 UNION 或一些如何構建查詢以便每個部分都可以使用索引(如果可以的話)。
if object_id('tempdb..#tbl') is not null drop table #tbl;
CREATE TABLE #tbl (
name varchar(20) not null,
groups int NOT NULL
);
insert into #tbl values('a', 35), ('a', 36), ('b', 35), ('c', 36), ('d', 37);
select *
from #tbl tbl
WHERE NOT EXISTS
(
SELECT COUNT(groups), name
FROM #tbl t
WHERE EXISTS
(
SELECT name
FROM #tbl tb
WHERE groups = 35
and tb.name=t.name
)
AND t.name = tbl.name
GROUP BY name
HAVING COUNT(groups)=1
)
;
uj5u.com熱心網友回復:
看起來您需要一個 exists() 條件。嘗試:
select *
from tbl t
where t.groups >= 35
and (
t.groups > 35
or exists(select * from tbl t2 where t2.name = t.name and t2.groups = 36)
)
還有其他方法可以排列 where 子句以達到相同的效果。預先設定 t.groups >= 35 條件應該使查詢優化器能夠利用組上的索引。
uj5u.com熱心網友回復:
您可以為此使用視窗計數
這避免了多次加入表
SELECT
name,
groups
FROM (
SELECT *,
Count36 = COUNT(CASE WHEN groups = 36 THEN 1 END) OVER (PARTITION BY name)
FROM tbl
WHERE groups >= 35
) tbl
WHERE groups >= 36 OR Count36 > 0;
資料庫<>小提琴
uj5u.com熱心網友回復:
嘗試這個:
DECLARE @tbl table ( [name] varchar(20) not null, groups int NOT NULL );
INSERT INTO @tbl VALUES
('a', 35), ('a', 36), ('b', 35), ('c', 36), ('d', 37);
DECLARE @group int = 35;
; WITH cte AS (
SELECT
[name]
, COUNT ( DISTINCT groups ) AS distinct_group_count
FROM @tbl
WHERE
groups >= @group
GROUP BY
[name]
)
SELECT t.* FROM @tbl AS t
INNER JOIN cte
ON t.[name] = cte.[name]
WHERE
cte.distinct_group_count > 1
OR t.groups > @group;
退貨
------ --------
| name | groups |
------ --------
| a | 35 |
| a | 36 |
| c | 36 |
| d | 37 |
------ --------
基本上,這將名稱結果限制為值 >= 35 且關聯多個不同組的組,或組值大于 35 的任何名稱。對您的資料進行了一些假設,但我相信邏輯仍然適用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/340083.html
標籤:sql sql-server 短信 ssms-2014
