Работа с запятыми в файле CSV

вы должны использовать другое соединение, что-то в этом направлении:

SELECT toD.dom_url AS ToURL, 
    fromD.dom_url AS FromUrl, 
    rvw.*

FROM reviews AS rvw

LEFT JOIN domain AS toD 
    ON toD.Dom_ID = rvw.rev_dom_for

LEFT JOIN domain AS fromD 
    ON fromD.Dom_ID = rvw.rev_dom_from

EDIT :

Все, что вы делаете, это соединение в таблицу несколько раз. Посмотрите на запрос в сообщении: он выбирает значения из таблиц отзывов (aliased as rvw), эта таблица предоставляет вам 2 ссылки на таблицу домена (FOR и FROM).

На этом этапе просто оставить слева таблицу Домен в таблице отзывов. Один раз (с псевдонимом toD) для FOR и второй раз (с псевдонимом fromD) для FROM.

Затем в списке SELECT вы выберете поля DOM_URL из обоих LEFT JOINS таблицы DOMAIN , ссылаясь на них псевдонимом таблицы для каждого, связанного с ссылкой на таблицу Domains, и псевдоним их как ToURL и FromUrl.

. Для получения дополнительной информации об aliasing в SQL читайте здесь здесь .

447
задан Svante 20 April 2009 в 21:07
поделиться

6 ответов

Как уже говорили другие, вам нужно избегать значений, которые включают кавычки. Вот небольшой CSV-ридер на C♯, который поддерживает значения в кавычках, включая встроенные кавычки и возврат каретки.

Кстати, это код, проверенный модулем. Я публикую его сейчас, потому что этот вопрос, кажется, часто поднимается, и другие могут не захотеть целую библиотеку, когда подойдет простая поддержка CSV.

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

using System;
public class test
{
    public static void Main()
    {
        using ( CsvReader reader = new CsvReader( "data.csv" ) )
        {
            foreach( string[] values in reader.RowEnumerator )
            {
                Console.WriteLine( "Row {0} has {1} values.", reader.RowIndex, values.Length );
            }
        }
        Console.ReadLine();
    }
}

Вот классы. Обратите внимание, что вы также можете использовать функцию Csv.Escape для записи действительного CSV.

using System.IO;
using System.Text.RegularExpressions;

public sealed class CsvReader : System.IDisposable
{
    public CsvReader( string fileName ) : this( new FileStream( fileName, FileMode.Open, FileAccess.Read ) )
    {
    }

    public CsvReader( Stream stream )
    {
        __reader = new StreamReader( stream );
    }

    public System.Collections.IEnumerable RowEnumerator
    {
        get {
            if ( null == __reader )
                throw new System.ApplicationException( "I can't start reading without CSV input." );

            __rowno = 0;
            string sLine;
            string sNextLine;

            while ( null != ( sLine = __reader.ReadLine() ) )
            {
                while ( rexRunOnLine.IsMatch( sLine ) && null != ( sNextLine = __reader.ReadLine() ) )
                    sLine += "\n" + sNextLine;

                __rowno++;
                string[] values = rexCsvSplitter.Split( sLine );

                for ( int i = 0; i < values.Length; i++ )
                    values[i] = Csv.Unescape( values[i] );

                yield return values;
            }

            __reader.Close();
        }
    }

    public long RowIndex { get { return __rowno; } }

    public void Dispose()
    {
        if ( null != __reader ) __reader.Dispose();
    }

    //============================================


    private long __rowno = 0;
    private TextReader __reader;
    private static Regex rexCsvSplitter = new Regex( @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))" );
    private static Regex rexRunOnLine = new Regex( @"^[^""]*(?:""[^""]*""[^""]*)*""[^""]*$" );
}

public static class Csv
{
    public static string Escape( string s )
    {
        if ( s.Contains( QUOTE ) )
            s = s.Replace( QUOTE, ESCAPED_QUOTE );

        if ( s.IndexOfAny( CHARACTERS_THAT_MUST_BE_QUOTED ) > -1 )
            s = QUOTE + s + QUOTE;

        return s;
    }

    public static string Unescape( string s )
    {
        if ( s.StartsWith( QUOTE ) && s.EndsWith( QUOTE ) )
        {
            s = s.Substring( 1, s.Length - 2 );

            if ( s.Contains( ESCAPED_QUOTE ) )
                s = s.Replace( ESCAPED_QUOTE, QUOTE );
        }

        return s;
    }


    private const string QUOTE = "\"";
    private const string ESCAPED_QUOTE = "\"\"";
    private static char[] CHARACTERS_THAT_MUST_BE_QUOTED = { ',', '"', '\n' };
}
217
ответ дан 22 November 2019 в 23:03
поделиться

Поскольку речь идет об общих методах, давайте начнем с практических правил:

  1. Не используйте CSV, используйте XML с библиотекой для чтения и записи XML-файла.

  2. Если вы должны использовать CSV. Сделайте это правильно и используйте бесплатную библиотеку для анализа и хранения файлов CSV.

Для обоснования 1), большинство анализаторов CSV не знают кодирования, поэтому, если вы не имеете дело с US-ASCII, у вас возникнут проблемы. Например, Excel 2002 хранит CSV в локальной кодировке без каких-либо замечаний о кодировке. Стандарт CSV не получил широкого распространения :(. С другой стороны, стандарт xml хорошо принят и хорошо обрабатывает кодировки.

Для обоснования 2), существует множество синтаксических анализаторов csv для почти всех языков, поэтому нет необходимости изобретать колесо, даже если решения выглядят симпатично. просто.

Чтобы назвать несколько:

  • для python используйте сборку в модуле csv

  • для проверки perl CPAN и Text :: CSV

  • для сборки php в build fgetcsv / Функции fputcsv

  • для проверки java Библиотека SuperCVS

Действительно, нет необходимости реализовывать это вручную, если вы не собираетесь анализировать это на встроенном устройстве.

0
ответ дан 22 November 2019 в 23:03
поделиться

Вы можете поставить двойные кавычки вокруг полей. Мне не нравится этот подход, поскольку он добавляет еще один специальный символ (двойная кавычка). Просто определите escape-символ (обычно с обратной косой чертой) и используйте его везде, где вам нужно что-то избежать:

data,more data,more data\, even,yet more

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

9
ответ дан 22 November 2019 в 23:03
поделиться

Поставьте двойные кавычки вокруг строк. Это обычно , что делает Excel .

Ала Эли,

вы избегаете двойных кавычек как двух двойные кавычки. Например "test1", "foo" "bar", "test2"

39
ответ дан 22 November 2019 в 23:03
поделиться

Формат CSV использует запятые для разделения значений, значения, содержащие возврат каретки, переводы строки, запятые или двойные кавычки, двойными кавычками. Значения, которые содержат двойные кавычки, заключаются в кавычки, и каждая буквальная кавычка экранируется непосредственно предшествующей кавычкой: например, 3 значения:

test
list, of, items
"go" he said

будут кодироваться как:

test
"list, of, items"
"""go"" he said"

Любое поле может быть заключено в кавычки, но только поля, содержащие запятые, CR / NL, или кавычки должны быть заключены в кавычки .

Нет реального стандарта для формата CSV, но почти все приложения следуют соглашениям, задокументированным здесь . RFC, который упоминался в другом месте, не является стандартом для CSV, это RFC для использования CSV в MIME и содержит некоторые нетрадиционные и ненужные ограничения, которые делают его бесполезным вне MIME.

75
ответ дан 22 November 2019 в 23:03
поделиться

Для 2017 года csv полностью указан - RFC 4180.

Это очень распространенная спецификация и полностью покрыт многими библиотеками (пример ).

Просто используйте любую легкодоступную библиотеку csv - то есть RFC 4180.


На самом деле есть спецификация для формата CSV и как обращаться с запятыми: appearing inside a field must be escaped by preceding it with another double quote. For example:

"aaa","b""bb","ccc"
389
ответ дан 22 November 2019 в 23:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: