2017-01-31 7 views
3

я следующие две таблицы:SQL с помощью раздела по таблицам

CREATE TABLE `T1` (
    `user`, 
    `str_to_match`, 
    `x` , 
    `y` 
); 

и

CREATE TABLE `T2` (
    `user`, 
    `ID`, 
    `str_to_match`, 
    `a`, 
    `b` 
); 

следующие значения вставляются в две таблицы:

INSERT INTO T1 VALUES ('U1','123', 23, 'YVAL'); 
INSERT INTO T1 VALUES ('U2','123', 21, 'YVAL1'); 
INSERT INTO T1 VALUES ('U2','121', 27, 'YVAL2'); 
INSERT INTO T1 VALUES ('U1','123', 28, 'YVAL3'); 
INSERT INTO T1 VALUES ('U1','456', 30, 'YVAL4'); 

INSERT INTO T2 VALUES ('U1', 1, '123', 'AVAL', 'BVAL'); 
INSERT INTO T2 VALUES ('U1', 2, '123', 'AVAL1', 'BVAL1'); 
INSERT INTO T2 VALUES ('U2', 3, '123', 'AVAL2', 'BVAL2'); 
INSERT INTO T2 VALUES ('U2', 4, '121', 'AVAL3', 'BVAL3'); 

я пытаюсь для ниже выход

T1.user, T1.str_to_match, SUM(T1.x), COUNT(T1.x), T2.ID, T2.a, T2.b 
U1, '123', 51, 2, 1, 'AVAL', 'BVAL' 
U1, '123', 51, 2, 2, 'AVAL1', 'BVAL1' 
U2, '123', 21, 1, 3, 'AVAL2', 'BVAL2' 
U2, '121', 27, 1, 4, 'AVAL3', 'BVAL3' 

Я использовал над разделом по таблице T1 для пользователя cols и str_to_match и могу получить агрегацию, , но не смог присоединиться к этому с таблицей T2, чтобы получить желаемый результат. Агрегация должна выполняться только в том случае, если в таблице T1 и T2 имеется совпадение для str_to_match col для одного и того же пользователя.

Вот мой текущий запрос, который работает по таблице T1

SELECT SUM(x) OVER (PARTITION BY user, str_to_match), 
COUNT(x) OVER (PARTITION BY user, str_to_match), 
str_to_match, 
user from T1 
+1

Тег dbms, который вы используете. (Проблема с продуктом.) – jarlh

+1

Какая СУБД вы используете? таблица create выглядит как MySQL, но она не поддерживает функции окна –

ответ

1

Это решение даст вам точный результат, который ожидают выше:

select distinct abc.[User], abc.str_to_match, abc.sumval, 
abc.countval,T2.ID, T2.a, T2.b 
from 
(select T1.[user],T1.str_to_match, SUM(T1.x) as sumval, COUNT(T1.x) as countval from T1 
group by T1.[user],T1.str_to_match) abc 
inner join t2 on t2.[user] = abc.[user] and t2.str_to_match = abc.str_to_match; 

Вы могут найти в приложенном скриншоте ссылку для запроса и вывода ниже:

query

Output

+0

безупречный. работает как шарм. вы могли бы также объяснить свой подход. Принимая ваш ответ. – user2077935

+0

Несколько раз мы идем к другому подходу, который на самом деле не имеет решения. То же самое в вашем запросе, вам не нужно использовать «раздел». Это можно сделать просто «GroupBy».Поэтому в моем первом подзапросе я выбрал все, что вы искали из таблицы, а затем сделал внутреннее соединение со второй таблицей на основе условия. –

1
Below query will give you the expected output 

select distinct t.str_to_match,t.[user],total,cnt 
,t2.id,t2.a,t2.b 
from (SELECT SUM(x) OVER (PARTITION BY [user], str_to_match) total, 
COUNT(x) OVER (PARTITION BY [user], str_to_match) cnt, 
str_to_match, 
[user] from @T1) as t 
join @T2 t2 on t.str_to_match = t2.str_to_match and t.[user] = t2.[user] 
order by t.[user],id 
+0

ну, str_to_match не должно быть разным. Что касается того же пользователя, он может иметь разные значения для cols t2.a, t2.b в той же строке. Пример: U1, '123', 51, 2, 1, 'AVAL', 'BVAL' U1, '123', 51, 2, 2, 'AVAL1', 'BVAL1' – user2077935

+1

Я сделал отличный выбор, потому что это делая кросс-соединение, поскольку в обеих таблицах есть одинаковые данные. Пример U1, '123' –

1

ли эта работа для вас? (Это стандарт SQL в BigQuery)

with T1 as(
select 'U1' as user, '123' as str_to_match, 23 as x, 'YVAL' as y union all 
select 'U2' as user, '123' as str_to_match, 21 as x, 'YVAL1' as y union all 
select 'U2' as user, '121' as str_to_match, 27 as x, 'YVAL2' as y union all 
select 'U1' as user, '123' as str_to_match, 28 as x, 'YVAL3' as y union all 
select 'U1' as user, '456' as str_to_match, 30 as x, 'YVAL4' as y 
), 
T2 as(
select 'U1' as user, 1 as ID, '123' as str_to_match, 'AVAL' as a, 'BVAL' as b union all 
select 'U1' as user, 2 as ID, '123' as str_to_match, 'AVAL1' as a, 'BVAL1' as b union all 
select 'U2' as user, 3 as ID, '123' as str_to_match, 'AVAL2' as a, 'BVAL2' as b union all 
select 'U2' as user, 4 as ID, '121' as str_to_match, 'AVAL3' as a, 'BVAL3' as b 
) 


select 
T1.user user, T1.str_to_match str_to_match, sum(T1.x) sum_x, count(T1.x) count_x, T2.ID ID, T2.a a, T2.b b 
from T1 
join T2 
on T1.user = T2.user and T1.str_to_match = T2.str_to_match 
group by 
user, str_to_match, ID, a, b 
order by user, id 

Я не уверен, если я правильно понял ваш вопрос, но для того, что я мог видеть в своем желаемом выходе вы хотите первый различать между значениями идентификаторов пользователей и затем запустить операции суммирования и подсчета, которые могут быть сделаны путем первого соединения T1 с T2.

+0

извините, но hardcoding str_to_match не поможет, так как строки в таблице близки к миллионам. – user2077935

1

не совсем ясно, но я думаю, LEFT JOIN с регулярной агрегации путь, чтобы идти (окна никаких функций, применимых здесь)

#standardSQL 
WITH T1 AS (
    SELECT 'U1' AS user, '123' AS str_to_match, 23 AS x, 'YVAL' AS y UNION ALL 
    SELECT 'U2' AS user, '123' AS str_to_match, 21 AS x, 'YVAL1' AS y UNION ALL 
    SELECT 'U2' AS user, '121' AS str_to_match, 27 AS x, 'YVAL2' AS y UNION ALL 
    SELECT 'U1' AS user, '123' AS str_to_match, 28 AS x, 'YVAL3' AS y UNION ALL 
    SELECT 'U1' AS user, '456' AS str_to_match, 30 AS x, 'YVAL4' AS y 
), 
T2 AS (
    SELECT 'U1' AS user, 1 AS ID, '123' AS str_to_match, 'AVAL' AS a, 'BVAL' AS b UNION ALL 
    SELECT 'U1' AS user, 2 AS ID, '123' AS str_to_match, 'AVAL1' AS a, 'BVAL1' AS b UNION ALL 
    SELECT 'U2' AS user, 3 AS ID, '123' AS str_to_match, 'AVAL2' AS a, 'BVAL2' AS b UNION ALL 
    SELECT 'U2' AS user, 4 AS ID, '121' AS str_to_match, 'AVAL3' AS a, 'BVAL3' AS b 
) 
SELECT 
    T2.user AS user, 
    T2.str_to_match AS str_to_match, 
    T2.ID AS ID, 
    T2.a AS a, 
    T2.b AS b, 
    SUM(T1.x) AS sum_x, 
    COUNT(T1.x) AS count_x 
FROM T2 LEFT JOIN T1 
ON T1.user = T2.user AND T1.str_to_match = T2.str_to_match 
GROUP BY user, str_to_match, ID, a, b