基于列值的SQL选择
我们有一个DB表,其中包含如下公司职务代码:基于列值的SQL选择,sql,sql-server,select,Sql,Sql Server,Select,我们有一个DB表,其中包含如下公司职务代码: ID Code Company 1 EW10 *** 2 EW10 DEU 3 EW10 DEC 4 EW20 *** 5 EW30 DEU 6 EW40 DEC 公司中的“***”表示企业级职务代码,可在雇主级DEU,DEC覆盖 我需要一个select语句,该语句返回具
ID Code Company
1 EW10 ***
2 EW10 DEU
3 EW10 DEC
4 EW20 ***
5 EW30 DEU
6 EW40 DEC
公司中的“***”表示企业级职务代码,可在雇主级DEU,DEC覆盖
我需要一个select语句,该语句返回具有以下条件的行:
如果没有公司特定代码,例如EW20,则返回
企业级行,如第4行
如果存在特定于公司的行,则返回所有特定于公司的行
我需要的结果集如下:
ID Code Company
2 EW10 DEU
3 EW10 DEC
4 EW20 ***
5 EW30 DEU
6 EW40 DEC
使用窗口功能。这比必要的稍微复杂一些,因为使用的是***而不是NULL。以下内容来回转换为NULL: 编辑: 您的问题是要返回所有行。但是,您的示例数据并非如此 我想你可能想要:
select t.*
from t
where t.company <> '***' or
not exists (select 1
from t t2
where t2.code = t.code and
t2.company <> '***'
);
或者,使用窗口功能:
select t.*
from (select t.*,
sum(case when company <> '***' then 1 else 0 end) over (partition by code) as num_notstars
from t
) t
where (num_notstars > 0 and company <> '***') or
(num_notstarts = 0);
对于这两种情况,均使用UNION:
select * from tablename
where Company <> '***'
union all
select * from tablename t
where not exists (
select 1 from tablename
where Code = t.Code and Company <> '***'
)
order by Id
只是另一种选择
范例
希望这能满足您的需要!: 这对你有用
对于以下两种情况,您可以使用OR来执行此操作:
SELECT *
FROM YourTable yt1
WHERE Company <> '***'
OR NOT EXISTS (
SELECT 1 FROM YourTable yt2
WHERE yt2.Code = yt1.Code AND yt2.Company <> '***'
)
您希望对行进行排序;公司级行胜于企业级行。为此使用秩或行号 如果您正在寻找一家特定的公司,您可以按如下方式排列您的行:
select *
from
(
select
mytable.*,
row_number() over (partition by code
order by case when company = '***' then 2 else 1 end) as rnk
from mytable
where company in ('DEC', '***')
) ranked
where rnk = 1
order by code;
对于所有公司,我建议首先选择这些公司,然后加入他们的比赛:
select *
from
(
select
c.company, m.id, m.code, m.company as setting_company,
row_number() over (partition by c.company, m.code
order by case when m.company = '***' then 2 else 1 end) as rnk
from (select distinct company from mytable where company <> '***') c
left join mytable m on m.company = c.company or m.company = '***'
) results
where rnk = 1
order by company, code;
演示:。此演示还包含另一种编写查询的方法。您也需要发布您的尝试。@BrianKE。我不明白你想做什么。为什么要过滤掉第1行?你说要返回所有行。@GordonLinoff我没说要返回所有行。我希望返回企业级代码,除非存在特定于公司的行。如果存在特定于公司的行,则返回该行。这就是为什么结果集中不存在第1行,特定于公司的代码会覆盖企业级代码。@BrianKE。代码是一列,不是一行。我把这个问题解释为该专栏的一个转变。实际上,您需要筛选行,因此不需要所有行。虽然示例数据有点澄清,但措辞含糊不清。这不起作用:但有人投了赞成票!
Select ID,Code,Company
From (
Select *
,RN = row_number() over (partition by [Code] order by [Company] desc)
From YourTable
) A
Where (Company<>'***' and RN=1)
or RN>1
ID Code Company
2 EW10 DEU
3 EW10 DEC
4 EW20 ***
5 EW30 DEU
6 EW40 DEC
SELECT id, Code, Company
FROM table main
WHERE
(
main. Company = '***'
AND NOT EXISTS (
SELECT code
FROM table sub
WHERE main.code = sub.code
AND main.id != sub.id
)
) OR company != '***'
Select * from tablename Where Company <> '***'
UNION
Select * from tablename Where Code Not In ( Select Code from #Sejaltable Where Company <> '***')
SELECT *
FROM YourTable yt1
WHERE Company <> '***'
OR NOT EXISTS (
SELECT 1 FROM YourTable yt2
WHERE yt2.Code = yt1.Code AND yt2.Company <> '***'
)
select *
from
(
select
mytable.*,
row_number() over (partition by code
order by case when company = '***' then 2 else 1 end) as rnk
from mytable
where company in ('DEC', '***')
) ranked
where rnk = 1
order by code;
select *
from
(
select
c.company, m.id, m.code, m.company as setting_company,
row_number() over (partition by c.company, m.code
order by case when m.company = '***' then 2 else 1 end) as rnk
from (select distinct company from mytable where company <> '***') c
left join mytable m on m.company = c.company or m.company = '***'
) results
where rnk = 1
order by company, code;