#sql #sql-server #case #sql-like #sql-server-2016
#sql #sql-сервер #случай #sql-подобный #sql-server-2016
Вопрос:
Это должно быть относительно просто. Я зарабатываю на жизнь, просматривая данные утверждений. У меня есть следующий гипотетический идентификатор утверждения: 17060C048388A3
Немного об этом, это A в 14-м символьном пространстве означает «Корректировка», а следующее число — это количество времени, которое было скорректировано. Так, например, это конкретное утверждение было скорректировано 3 раза. К сожалению, идентификаторы претензий 17060C048388A1, 17060C048388A2 и 17060C048388A3 (отображаются все три настройки). Как мне выбрать только самую высокую настройку, чтобы избежать дублирования при подсчете этих утверждений. Не все утверждения скорректированы, поэтому не все они имеют буквы A и не все 15 символов.
Итак, я думаю, мне нужно запустить оператор case следующим образом:
SELECT DISTINCT TOP 10000 *,
CASE WHEN CLAIMID LIKE '%A%' THEN ??????
Любые предложения по получению следующей по старшинству цифры после «A» в идентификаторе утверждения, если в идентификаторе утверждения есть «A». Итак, если в утверждении было 8 корректировок, я хочу видеть только ту, которая заканчивается на A8.
Заранее спасибо, ребята, Грег
Комментарии:
1. какую СУБД (mysql, sql-server, oracle, postgres) вы используете? пожалуйста, отметьте свой вопрос.
2. Sql_Server 2016 Management Studio
3. Если выше не было ясно, буква «А», указывающая на корректировки, не всегда попадает на 14-ю позицию.
4. Что вы, ребята, думаете об этом. Просматривая данные, буква «А» может находиться либо на 13-й, либо на 14-й позиции. Разве это не должно сработать? <br/>`
SELECT DISTINCT claimid <br/> CASE WHEN SUBSTRING(CLAIMID, 14, 1) = 'A' Then Max(ClaimID) <br/> WHEN SUBSTRING(CLAIMID, 13, 1) = 'A' Then Max(ClaimID) End as MaxClaimID <br/> FROM PLANREPORT_QNXT_LA.DBO.CLAIM <br/> WHERE CLAIMID LIKE '%A%' <br/> group by claimid
<br/>
Ответ №1:
С помощью CTE:
with cte as(
select
claimid,
case
when claimid like '%A%' then left(claimid, charindex('A', claimid) - 1)
else claimid
end claim,
case
when claimid like '%A%' then cast(right(claimid, len(claimid) - charindex('A', claimid)) as int)
else 0
end adjustment
from tablename
)
select distinct top 10000 t.*
from tablename t inner join (
select
claim
case max(adjustment)
when 0 then ''
else 'A' cast(max(adjustment) as varchar(10))
end claimid
from cte
group by claim
) g on g.claimid = t.claimid
Посмотрите демонстрационную версию.
Для этого примера данных:
> claimid | value
> :------------- | :----
> 17060C048388A1 | a
> 17060C048388A2 | b
> 17060C04838811 | c
> 17060C04838866 | d
> 17060C04838855 | e
> 17060C048388A3 | f
> 17060C04838899 | g
результаты таковы:
> claimid | value
> :------------- | :----
> 17060C04838811 | c
> 17060C04838866 | d
> 17060C04838855 | e
> 17060C048388A3 | f
> 17060C04838899 | g
Ответ №2:
это будет работать еще проще;
select * from Table1 where
regexp_like("column1",substr("column1",1,instr("column1",'A'))||
(select max(substr("column1",-1)) from Table1) );`
проверьте это: http://sqlfiddle.com/#!4/cb16f/7
Ответ №3:
Это то, что сработало для меня (при условии, что я не замечу никаких ошибок). Я взял примеры из всех комментариев и собрал их вместе, так что спасибо всем, кто ответил.
SELECT DISTINCT SUBSTRING(CLAIMID, 1,13) MAX(RIGHT(CLAIMID, 2)) AS
MAX_CLAIM_ADJUSTMENT
FROM LA_TEMP.DBO.ITEM19
WHERE (SUBSTRING(CLAIMID, 14, 1) = 'A'
OR SUBSTRING(CLAIMID, 13, 1) = 'A')
GROUP BY left(CLAIMID, 13)
UNION
SELECT DISTINCT SUBSTRING(CLAIMID, 1,14) MAX(RIGHT(CLAIMID, 1)) AS
MAX_CLAIM_ADJUSTMENT
FROM LA_TEMP.DBO.ITEM19
WHERE (SUBSTRING(CLAIMID, 15, 1) = 'A'
OR SUBSTRING(CLAIMID, 14, 1) = 'A')
GROUP BY left(CLAIMID, 14)
ORDER BY MAX_CLAIM_ADJUSTMENT
Я заметил, что буква «А» может быть либо 13-м, либо 14-м символом.
Комментарии:
1. Ваш код завершается ошибкой, когда число после A длиннее 1 цифры, потому что вы получаете это число в виде строки, поэтому, если существует A10, вы получите A9 как максимум.
Ответ №4:
Я снова посмотрел на ваш вопрос и создал следующее решение:
SELECT base, MAX(adjustment) AS max_adjustment, base IIF(MAX(adjustment) > 0, 'A', '') MAX(adjustment) max_adjusted_claim
FROM (
SELECT
IIF(PATINDEX('%A%', ClaimID) = 0, ClaimID, LEFT(ClaimID, PATINDEX('%A%', ClaimID)-1)) AS base,
REPLACE(REVERSE(LEFT(REVERSE(ClaimID), PATINDEX('%A%', REVERSE(ClaimID)))), 'A', '') AS adjustment
FROM table_name
)t GROUP BY base
Комментарии:
1. Если выше не было ясно, буква «А», указывающая на корректировки, не всегда попадает на 14-ю позицию.
2. @GregoryBrauninger — Я обновил свое решение, теперь оно должно работать для многих возможностей (посмотрите демонстрацию с некоторыми тестовыми значениями).