Получить список записей, имена которых начинаются с определенного значения и игнорировать в случае других значений для разных строк - PullRequest
0 голосов
/ 10 апреля 2019

Я пытаюсь получить записи Col A, основанные на первом символе в Col B. Если первый символ в Col B совпадает со всеми уникальными значениями Col A, то возвращается значение Col A.Если первый символ в столбце B не совпадает с другими первыми значениями в столбце B, то значение столбца A возвращать не следует.Это в Oracle SQL.

select T1.colA,count(*) from colTables T1 where T1.colA in (
select T2.colA from colTables T2 where T2.colB like '1%'
group by T2.colA)
group by T1.colA;



Col A | Col B
    101|12541
    101|15475
    101|19874
    102|12544
    102|22549
    102|12537
    103|22549
    103|28747
    104|72549
    104|82549
    104|82549
    105|12549
    105|12531
    105|12589
    106|75448
    106|71544

Мой запрос дает следующий вывод

  ColA | Count
    101|3
    102|3
    105|3

, но я хочу, чтобы вывод был

   ColA| Count
    101|3
    105|3

Также .. Iя проверяю, есть ли какие-либо средства, где я могу опустить T2.colB like '1%', чтобы получить вывод следующим образом

   ColA| Count
    101|3  -- All values in col B starts with 1
    103|2  -- All values in col B starts with 2
    105|3  -- All values in col B starts with 1
    106|2  -- All values in col B starts with 7

Ответы [ 2 ]

2 голосов
/ 10 апреля 2019

Если вы хотите, чтобы все значения colB начинались с 1, тогда:

select t.colA, count(*)
from colTables t
group by t.colA
having sum(case when t.colB like '1%' then 1 else 0 end) = count(*);

Вы также можете сформулировать это другими способами, например:

having min(t.colB) >= '1' and
       max(t.colB) < '2'

Если вы просто хотите, чтобы значения colB начинались с одной и той же буквы для всех colA, используйте:

having min(substr(t.colB, 1, 1)) = max(substr(t.colB, 1, 1))
0 голосов
/ 10 апреля 2019

Схема

CREATE TABLE tbl (
  "cola" varchar(100),
  "colb" varchar(100)
);

INSERT INTO tbl
  ("cola", "colb")
VALUES
  ('101', '12541'),
  ('101', '15475'),
  ('101', '19874'),
  ('102', '12544'),
  ('102', '22549'),
  ('102', '12537'),
  ('103', '22549'),
  ('103', '28747'),
  ('104', '72549'),
  ('104', '82549'),
  ('104', '82549'),
  ('105', '12549'),
  ('105', '12531'),
  ('105', '12589'),
  ('106', '75448'),
  ('106', '71544');

Запрос

Тест в реальном времени: https://www.db -fiddle.com / f / iquHToVTGz8JxnWSaT2ChD / 4

select cola, count(*)
from tbl
group by cola
having (cola, count(*))
in (                      
  select 
      cola, count(*)
  from tbl
  where colb like '1%'
  group by cola
)
order by cola;

Выход:

| cola | count |
| ---- | ----- |
| 105  | 3     |
| 101  | 3     |

Другой подход работает на СУБД, которая не поддерживает кортеж в предложении IN. Используйте EXISTS:

select y.cola, count(*) as y_count
from tbl y
group by y.cola
having exists
(
  select 
      null -- does not matter
  from tbl x
  -- this matters
  where x.cola = y.cola 
     and x.colb like '1%'
  group by x.cola
  having count(x.cola) = count(y.cola)
)
order by y.cola;
...