Reputation: 58
I have a table like this:
[invoice_lines]
:
id (int), customerid (int), price (int), productname (text)
I want to query this table, and extract all rows. But I want an additional column which can be a 1/0 column, which checks whether or not there exists a row where productname = 'SLA' AND customerid = customerid.
So lets say I have a row which looks like this:
id customerid price productname
-----------------------------------------
1 134 125 Internet
I want this row to be extracted, but I want to see if there is any rows with the productname = 'SLA' AND customerid = '134'. If there is a row which meets these criterias, I want the additional column (lets call it SLA) to have the value 1. If it does not exist, I would like the value to be 0.
Any pointers?
Upvotes: 1
Views: 59
Reputation: 46202
For all invoice lines in the table, I suggest a CASE expression around a windowing function. A composite clustered/covering index with a key of customerid and productname to provide the best performance.
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;
A correlated subquery can also do the job but there will probably be a tipping point where the execution plan changes to handle a large number of invoiced lines.
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;
Upvotes: 0
Reputation: 1269693
You should just use exists
in the select
. Or, use conditional aggregation with a window function. This is probably the most efficient method:
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;
Upvotes: 0
Reputation: 35780
I would do this with CROSS APPLY
because joins may produce duplicate rows:
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
Upvotes: 0
Reputation: 204756
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'
Upvotes: 3
Reputation: 538
You can use case
on your new column which will check that :
select id, customerid,price,productname
case when productname = 'SLA' and customerid = '134' then 1 else 0 end as SLA
from [invoice_lines]
Upvotes: 0