[sql] Выбрать строки по нескольким критериям в 2 колонках
а где в запросах prop_name и prop_value? И что такое map? ужасное описание.
переписал
SELECT user_id FROM
(SELECT user_id, COUNT(prop_name) AS num
FROM user
WRE (prop_name = 'ancestry' and prop_value = 'Germany') or (prop_name = 'age ' and prop_value = '27')
GROUP BY user_id)
WRE num = 2
В синтаксисе может где-то ошибся, руками не пишу.
Так не годится?
SELECT DISTINCT (user_id)
FROM
(select * from
(select * from user where prop_name = 'age ' and prop_value = '27')
where prop_name = 'ancestry' and prop_value = 'Germany')
В синтаксисе мог налажать.
select * from ( select * from user pivot(max(prop_value) for prop_name in ('age' age,'ancestry' ancestry ) t
where t.age=27 and and t.ancestry= 'Germany'
Upd. не подходит под условие не полного списка, можно сделать и с полным списком, но через xml, не думаю, что будет быстрее.
select u.user_id from user u
join xmltable('for $root in $data/data/row return $root'
passing xmltype('<data><row><name>ancestry</name><value>Ger</value></row><row><name>age</name><value>27</value></row></data>') as "data" columns
name varchar2(512 char) path 'name',
value varchar2(512 char) path 'value') p
on( p.name=u.prop_name and p.value=u.prop_value)
group by u.user_id
having count(*) >= 2
Сервис, который будет готовить select написан на js. То есть ему на вход подаётся массив name-value, он выплёвывает селект.
То есть вариант решает задачу. Твой вариант тоже решает, но сложнее.
Правильно я понимаю, что на нескольких десятках тысяч записей все запросы должны шустро отрабатывать?
Про js не понял, обычно js просто отсылает данные на интерфейс, с интерфейса идут в БД, и потом js обрабатывает полученные данные.
На счет шустрости все индивидуально.
var sql = "SELECT user_id FROM (SELECT user_id, COUNT(prop_name) AS num FROM user WRE ";
for (var i = 0; i < arr.length; i++) {
sql += ''(prop_name = " + arr[i].name + " and prop_value = " arr[i].value + ") OR";
}
sql += " GROUP BY user_id) WRE num = " + arr.length;
return sql;
Так вроде работать будет (за исключением мелких ошибок в духе OR без условия но я бы канеш лучше делал хранимки в оракле, плюс тут потенциальные дыры в плане скул инжекшин.
Так запрос в любом случае нужно редактировать. Несложно количество параметров подставить.
select
t1.user_id
from
TABLE_NAME t1
inner join (
select
prop_name = 'ancestry'
, prop_value = 'Germany'
from
dual
union all
select
prop_name = 'age'
, prop_value = 27
from
dual
) t2
on 1 = 1 and t1.prop_name = t2.prop_name and t1.prop_value = t2.prop_value
group by
t1.user_id
having
count(*) = 2 -- количество условий
Всё что в скобках - надо сгенерить, вместо двойки тоже подставить.
Предварительно убедиться, что в таблице нет одинаковых строк. (2 раза age=27 для одного и того же user_id)
ps. В каракулях же так делается селект из ниоткуда ?
ну и для
Предварительно убедиться, что в таблице нет одинаковых строк. (2 раза age=27 для одного и того же user_id)
я бы уник ключ на все три столбца повесил бы, наверное.
Да, сорри, ща вглянулся и понял что написал то же самое.
Оставить комментарий
Anton456
Задача похожа на эту.Только структура таблицы такая.
1
1
2
3
Ну и в итоге надо запилить сервис, который бы по входящему массиву name-value генерил SELECT, который бы возвращал удовлетворяющие всем условиям из массива name-value user_id.
Разворачивать свойства в колонки не хочется, потому что во-первых их список не окончательный и может меняться в обе стороны. Во-вторых (ну это мелочь, да, можно и null'ами забить) ни одно из свойств не является обязательным.
Для задачи выбрать всех пользователей 27 лет, родившихся в Германии, на вход сервиса приходит arr[]: arr[0].name = 'ancestry', arr[0].value = 'Germany', arr[1].name = 'age', arr[1].value = '27')
в принципе, наверное подходит такое решение (допиленный ответ с SO):
Его по крайней мере можно слепить автоматически легко, но это вложенные запросы и выглядит как гавно.
В принципе, вся задача выглядит как гавно, конечно.
Может у неё есть какое-то очевидное и простое решение?
Если что, oracle.