这是我的数据:
INT CHAR(2) CHAR(4)
+------+--------------+------------+
| ID | SHORT_CODE | LONG_CODE |
+------+--------------+------------+
| 1 01 0100
| 2 01 0110
| 3 01 0120
| 4 02 0200
| 5 02 0212
| 6 02 0299
| 7 02 0211
我正在寻找将输出此结果的查询:
+--------------+------------+-------------+
| SHORT_CODE | LONG_CODE | IS_FIRST |
+--------------+------------+-------------+
| 02 0200 false
| 02 0211 true
| 02 0212 false
| 02 0299 false
这是我试过的
SELECT
short_code,
long_code,
CASE
WHEN long_code LIKE '021%'
THEN 'true'
ELSE 'false'
END as is_first
FROM
MY_TABLE
WHERE
short_code='02'
ORDER BY
long_code ASC;
此查询还会为true
打印0212
。我希望true
仅用于第一个匹配的行。
我怎样才能实现这一目标?
此问题中的示例代码可用here。
Oracle 10gR2
答案 0 :(得分:1)
您可以创建一个额外的列is_match
,以显示该行是否与like '021%'
条件匹配。然后,您可以在匹配的行分区和不匹配的行分区中分配升序行号rn
。匹配且行号为1的行是您要查找的行。
SELECT short_code
, long_code
, CASE
WHEN is_match = 1 and rn = 1 THEN 'true'
ELSE 'false'
END as is_first
FROM (
SELECT short_code
, long_code
, is_match
, row_number() over (
partition by is_match
order by long_code) as rn
FROM (
SELECT short_code
, long_code
, case
when long_code like '%021%' then 1
else 0
end as is_match
FROM MY_TABLE
WHERE short_code = '02'
) s1
) s2
ORDER BY
long_code;
答案 1 :(得分:1)
你可以用jimmy-rig row_number()
来做这件事,但这可能有点麻烦。
我能找到的最好的想法是创建一个伪列prefix
,这样我就可以先排序所有匹配的行,然后按long_code
排序:
SELECT short_code,
long_code,
CASE row_number() over (order by prefix desc, long_code asc)
WHEN 1 THEN 'true'
ELSE 'false'
END AS is_first
FROM (SELECT short_code,
long_code,
CASE
WHEN long_code LIKE '021%' THEN 1
ELSE 0
END as prefix
FROM my_table
WHERE short_code='02'
)
ORDER BY long_code ASC;
结果也显示在SQLFiddle。
中答案 2 :(得分:0)
SELECT m.*,
(CASE WHEN b.Id IS NOT NULL THEN 'True' ELSE 'False' END) as First
FROM MY_TABLE m
LEFT JOIN
(
SELECT Id FROM
(
SELECT Id
FROM MY_TABLE
WHERE Long_Code LIKE '021%'
AND Short_Code = '02'
ORDER BY Long_Code
) C
WHERE RowNum = 1
) B
ON b.Id = m.Id
WHERE m.Short_Code = '02';