Reputation: 59
I have to select the longest phrase that has points>0
but being contained in a phrase which has points=0
, if you look at the demo than the rows in output would be number 3 and 6:
http://sqlfiddle.com/#!18/e954f/1/0
many thanks in advance.
Upvotes: 0
Views: 90
Reputation: 37472
You can use an inner join comparing the phrases with a LIKE
to get only the ones contained in another phrase. Filter for the point in a WHERE
clause. Then get the rank()
partitioned by the phrase from the joined instance and ordered by the length descending. In an outer SELECT
only get the ones with a rank of one.
SELECT x.id,
x.phrase,
x.points
FROM (SELECT w1.id,
w1.phrase,
w1.points,
rank() OVER (PARTITION BY w2.phrase
ORDER BY len(w1.phrase) DESC) r
FROM words w1
INNER JOIN words w2
ON w2.phrase LIKE concat(w1.phrase, '%')
WHERE w2.points = 0
AND w1.points > 0) x
WHERE x.r = 1;
Edit:
To include the other phrase:
SELECT x.id,
x.phrase,
x.other_phrase,
x.points
FROM (SELECT w1.id,
w1.phrase,
w2.phrase other_phrase,
w1.points,
rank() OVER (PARTITION BY w2.phrase
ORDER BY len(w1.phrase) DESC) r
FROM words w1
INNER JOIN words w2
ON w2.phrase LIKE concat(w1.phrase, '%')
WHERE w2.points = 0
AND w1.points > 0) x
WHERE x.r = 1;
Upvotes: 1
Reputation: 147156
You can use a CTE to find all phrases with positive points which are a substring of a phrase with 0 points. Then you can find the maximum length of the substrings associated with each 0 point phrase, and JOIN
that back to the CTE to get the phrase that matches that condition:
WITH cte AS (
SELECT w1.*, w2.id AS w2_id
FROM words w1
JOIN (SELECT *
FROM words
WHERE points = 0) w2 ON w1.phrase = LEFT(w2.phrase, LEN(w1.phrase))
WHERE w1.points > 0
)
SELECT cte.id, cte.phrase, points
FROM cte
JOIN (SELECT w2_id, MAX(LEN(phrase)) AS max_len
FROM cte
GROUP BY w2_id) cte_max ON cte_max.w2_id = cte.w2_id AND cte_max.max_len = LEN(cte.phrase)
Output:
id phrase points
3 tool box online 1
6 stone road 1
Upvotes: 1
Reputation: 314
You will get from max to min length of phrase where points>0
SELECT *, LEN(phrase) AS Lenght FROM words where points>0 ORDER BY LEN(phrase) DESC
And if you want the longest phrase
SELECT TOP 1 *, LEN(phrase) AS Lenght FROM words where points>0 ORDER BY LEN(phrase) DESC
Upvotes: 0