我有一张这样的表:
[invoice_lines]
:
id (int), customerid (int), price (int), productname (text)
我想查询此表,并提取所有行。但是我想要一个额外的列,它可以是1/0列,它检查是否存在productname ='SLA'和customerid = customerid的行。
所以我想说我有一行看起来像这样:
id customerid price productname
-----------------------------------------
1 134 125 Internet
我希望提取此行,但我想查看是否有任何行,其中productname ='SLA'和customerid ='134'。如果有一行符合这些标准,我希望附加列(让我们称之为SLA)的值为1.如果它不存在,我希望该值为0.
任何指针?
答案 0 :(得分:3)
select t1.*,
case when t2.customerid is not null
then 1
else 0
end as result_check
from invoice_lines t1
left join invoice_lines t2 on t1.customerid = t2.customerid
and t2.productname = 'SLA'
答案 1 :(得分:0)
您可以在新列上使用case
来检查:
select id, customerid,price,productname
case when productname = 'SLA' and customerid = '134' then 1 else 0 end as SLA
from [invoice_lines]
答案 2 :(得分:0)
我会使用CROSS APPLY
执行此操作,因为联接可能会产生重复的行:
SELECT *
FROM TableName t1
CROSS APPLY ( SELECT CASE WHEN EXISTS ( SELECT *
FROM TableName t2
WHERE t2.customerid = t1.customerid AND t2.productname = 'SLA' )
THEN 1
ELSE 0
END AS SLA
) a
答案 3 :(得分:0)
您应该在exists
中使用select
。或者,使用带窗函数的条件聚合。这可能是最有效的方法:
select il.*,
(case when sum(case when productname = 'SLA' then 1 else 0 end) over (partition by customerid)
then 1
else 0
end) as sla
from invoice_lines il;
答案 4 :(得分:0)
对于表格中的所有发票行,我建议在窗口函数周围使用CASE表达式。具有customerid和productname键的复合聚簇/覆盖索引,以提供最佳性能。
SELECT id
, customerid
, price
, productname
, CASE SUM(CASE WHEN productname = 'SLA' THEN 1
ELSE 0
END) OVER ( PARTITION BY customerid )
WHEN 0 THEN 0
ELSE 1
END AS SLA
FROM invoice_lines il;
相关子查询也可以完成这项工作,但可能会有一个临界点,执行计划会更改以处理大量的发票行。
SELECT id
, customerid
, price
, productname
, CASE WHEN EXISTS ( SELECT *
FROM dbo.invoice_lines b
WHERE b.customerid = a.customerid
AND b.productname = 'SLA' ) THEN 1
ELSE 0
END AS SLA
FROM dbo.invoice_lines AS a;