2016-11-26 3 views
1

Я совершенно новой для у-SQL, пытаясь решитьU-SQL скрипт для поиска строки, то GroupBy эту строку и получить счетчик отдельных файлов

str1 = \ Global \ Европа \ Москва \ 12345 \ fILE1.TXT

str2 = \ global.bee.com \ Европа \ Москва \ 12345 \ fILE1.TXT

str3 = \ Global \ Европа \ амстердам \ 54321 \ File1.Rvt STR4 = \ global.bee .com \ europe \ amsterdam \ 12345 \ File1.Rvt

case1: как я могу получить только «\ eur ope \ Moscow \ 12345 \ File1.txt "из переменной строк str1 & str2, я хочу просто взять (" \ europe \ Moscow \ 12345 \ File1.txt ") из str1 и str2, затем" Groupby (\ global \ europe \ Москва \ 12345) "и принять подсчет отдельных файлов с пути ("" \ Европа \ Москва \ 12345 \")

поэтому выход будет что-то вроде этого:

distinct_filesby_Location_Date

в разрешите описанный выше случай, я попробовал код u-sql, но не совсем уверен, что я пишу правильный скрипт или нет:

@inArray = SELECT new SQL.ARRAY<string>(
       filepath.Contains("\\europe")) AS path 
    FROM @t; 

@filesbyloc = 
    SELECT [ID], 
     path.Trim() AS path1 
    FROM @inArray 
    CROSS APPLY 
    EXPLODE(path1) AS r(location); 

OUTPUT @filesbyloc 
TO "/Outputs/distinctfilesbylocation.tsv" 
USING Outputters.Tsv(); 

любая помощь вам очень благодарна.

ответ

1

Один из подходов к этому состоит в том, чтобы поместить все строки, с которыми вы хотите работать в файле, например strings.txt, и сохранить их в своей папке ввода U-SQL. Также есть файл с городами, в которых вы хотите совместить, например cities.txt. Тогда попробуйте следующий U-SQL скрипт:

@input = 
    EXTRACT filepath string 
    FROM "/input/strings.txt" 
    USING Extractors.Tsv(); 

// Give the strings a row-number 
@input = 
    SELECT ROW_NUMBER() OVER() AS rn, 
      filepath 
    FROM @input; 


// Get the cities 
@cities = 
    EXTRACT city string 
    FROM "/input/cities.txt" 
    USING Extractors.Tsv(); 

// Ensure there is a lower-case version of city for matching/joining 
@cities = 
    SELECT city, 
      city.ToLower() AS lowercase_city 
    FROM @cities; 


// Explode the filepath into separate rows 
@working = 
    SELECT rn, 
      new SQL.ARRAY<string>(filepath.Split('\\')) AS pathElement 
    FROM @input AS i; 

// Explode the filepath string, also changing to lower case 
@working = 
    SELECT rn, 
      x.pathElement.ToLower() AS pathElement 
    FROM @working AS i 
     CROSS APPLY 
      EXPLODE(pathElement) AS x(pathElement); 


// Create the output query, joining on lower case city name, display, normal case name 
@output = 
    SELECT c.city, 
      COUNT(*) AS records 
    FROM @working AS w 
     INNER JOIN 
      @cities AS c 
     ON w.pathElement == c.lowercase_city 
    GROUP BY c.city; 


// Output the result 
OUTPUT @output TO "/output/output.txt" 
USING Outputters.Tsv(); 

//OUTPUT @working TO "/output/output2.txt" 
//USING Outputters.Tsv(); 

Мои результаты:

My output file results

HTH

+1

Большое спасибо wBob, вы действительно упростили мою работу, я просто искал поиск в Google, чтобы найти способ сделать это. Боб еще одна вещь, если вы посмотрели на мою выходную ссылку, вы должны были увидеть 2 поля «Местоположение» и «Дата», что означает местоположение по количеству файлов по дате. Как это можно было бы добавить в вышеупомянутое решение, которое вы предоставили. пожалуйста, порекомендуйте. еще раз большое спасибо за ответ на мой пост так быстро :-) –

+0

Отлично, вы должны подумать о том, чтобы отметить это как ответ! – wBob

+0

Где находится дата? Это не ясно из ваших данных примера. Это в имени файла, или вам нужно собрать его из самого файла? – wBob

1

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

@d = 
    EXTRACT path string, 
      user string, 
      num1 int, 
      num2 int, 
      start_date string, 
      end_date string, 
      flag string, 
      year int, 
      s string, 
      another_date string 
    FROM @"\users\temp\citypaths.txt" 
    USING Extractors.Tsv(encoding: Encoding.Unicode); 

// I assume that you have only one DateTime format culture in your file. 
// If it becomes dependent on the region or city as expressed in the path, you need to add a lookup. 
@d = 
SELECT new SqlArray<string>(path.Split('\\')) AS steps, 
     DateTime.Parse(end_date, new CultureInfo("fr-FR", false)).Date.ToString("yyyy-MM-dd") AS end_date 
FROM @d; 

// This assumes your paths have a fixed formatting/mapping into the city 
@d = 
SELECT steps[4].ToLowerInvariant() AS city, 
     end_date 
FROM @d; 

@res = 
SELECT city, 
     end_date, 
     COUNT(*) AS count 
FROM @d 
GROUP BY city, 
     end_date; 

OUTPUT @res 
TO "/output/result.csv" 
USING Outputters.Csv(); 

// Now let's pivot the date and count. 

OUTPUT @res2 
TO "/output/res2.csv" 
USING Outputters.Csv(); 
     @res2 = 
SELECT city, MAP_AGG(end_date, count) AS date_count 
FROM @res 
GROUP BY city; 

// This assumes you know exactly with dates you are looking for. Otherwise keep it in the first file representation. 
@res2 = 
SELECT city, 
     date_count["2016-11-21"]AS [2016-11-21], 
     date_count["2016-11-22"]AS [2016-11-22] 
FROM @res2; 

UPDATE ПОСЛЕ ПОЛУЧЕНИЯ НЕКОТОРЫХ ПРИМЕР ДАННЫХ В ЧАСТНОМ EMAIL:

на основе данных, которые вы послали меня (после извлечения и подсчета городов, которые вы или могли бы сделать с присоединиться, как указано в Ответ Боба, где вам нужно знать свои города заранее, или взять строку из местоположения города на пути, как в моем примере, где вам не нужно знать города заранее), вы хотите развернуть набор строк city, count, date в набор строк date, city1, city2, ... были каждая строка содержит дату и подсчеты для каждого города.

Вы можете легко настроить мой пример выше, изменяя расчеты @res2 следующим образом:

// Now let's pivot the city and count. 
@res2 = SELECT end_date, MAP_AGG(city, count) AS city_count 
     FROM @res 
     GROUP BY end_date; 

// This assumes you know exactly with cities you are looking for. Otherwise keep it in the first file representation or use a script generation (see below). 
@res2 = 
SELECT end_date, 
     city_count["istanbul"]AS istanbul, 
     city_count["midlands"]AS midlands, 
     city_count["belfast"] AS belfast, 
     city_count["acoustics"] AS acoustics, 
     city_count["amsterdam"] AS amsterdam 
FROM @res2; 

Обратите внимание, что, как в моем примере, вам нужно будет перечислить все города в операторе поворота, посмотрев его в столбце SQL.MAP. Если это неизвестно, вы должны сначала отправить скрипт, который создает для вас сценарий.Например, если ваш набор city, count, date находится в файле (или вы можете просто дублировать инструкции для генерации набора строк в сценарии генерации и сгенерированного скрипта), вы можете записать его как следующий скрипт. Затем возьмите результат и отправьте его как фактический сценарий обработки.

// Get the rowset (could also be the actual calculation from the original file 
@in = EXTRACT city string, count int?, date string 
     FROM "https://stackoverflow.com/users/temp/Revit_Last2Months_Results.tsv" 
     USING Extractors.Tsv(); 

// Generate the statements for the preparation of the data before the pivot 
@stmts = SELECT * FROM (VALUES 
        ("@s1", "EXTRACT city string, count int?, date string FROM \"https://stackoverflow.com/users/temp/Revit_Last2Months_Results.tsv\" USING Extractors.Tsv();"), 
        ("@s2", "SELECT date, MAP_AGG(city, count) AS city_count FROM @s1 GROUP BY date;") 
       ) AS T(stmt_name, stmt); 

// Now generate the statement doing the pivot 
@cities = SELECT DISTINCT city FROM @in2; 

@pivots = 
SELECT "@s3" AS stmt_name, "SELECT date, "+String.Join(", ", ARRAY_AGG("city_count[\""+city+"\"] AS ["+city+"]"))+ " FROM @s2;" AS stmt 
FROM @cities; 

// Now generate the OUTPUT statement after the pivot. Note that the OUTPUT does not have a statement name. 
@output = 
SELECT "OUTPUT @s3 TO \"/output/pivot_gen.tsv\" USING Outputters.Tsv();" AS stmt 
FROM (VALUES(1)) AS T(x); 

// Now put the statements into one rowset. Note that null are ordering high in U-SQL 
@result = 
SELECT stmt_name, "=" AS assign, stmt FROM @stmts 
UNION ALL SELECT stmt_name, "=" AS assign, stmt FROM @pivots 
UNION ALL SELECT (string) null AS stmt_name, (string) null AS assign, stmt FROM @output; 

// Now output the statements in order of the stmt_name 
OUTPUT @result 
TO "/pivot.usql" 
ORDER BY stmt_name 
USING Outputters.Text(delimiter:' ', quoting:false); 

Теперь загрузите файл и отправьте его.

+0

привет Майкл, спасибо за ваши комментарии, я попытался применить код, который вы предложили выше, который может быть решением, но согласно моему требованию это не дает мне ожидаемого результата. если вы можете поделиться своим «адресом электронной почты», я могу отправить вас подробно, так как это место очень ограничено, чтобы делиться деталями. –

+0

Вы можете связаться со мной по адресу usql в Microsoft. Одна вещь, которую я рекомендую, - это посмотреть на код и определить различия между моими предположениями и вашим сценарием, чтобы определить места, которые вам могут понадобиться, чтобы изменить образец. –

 Смежные вопросы

  • Нет связанных вопросов^_^