ExcelテーブルでSQLクエリを実行するにはどうすればよいですか?


83

nullではない電話番号フィールドを持つAZでソートされたすべての姓フィールドの別のテーブルからサブテーブルを作成しようとしています。SQLを使用するとこれを非常に簡単に行うことができますが、Excel内でSQLクエリを実行する方法がわかりません。データをpostgresqlにインポートして、そこでクエリを実行したいのですが、それは少し過剰に思えます。

私がやろうとしていることに対して、SQLクエリSELECT lastname, firstname, phonenumber WHERE phonenumber IS NOT NULL ORDER BY lastnameがそのトリックを実行します。Excelがネイティブに実行できないものにするのは単純すぎるようです。Excel内からこのようなSQLクエリを実行するにはどうすればよいですか?


これをSQL自体で実行しますか、それともアプリケーション内から実行しますか?
ジョンビンガム2013

2
私はこれを徹底的に調査し、exceldevelopmentplatform.blogspot.com / 2018/10
S Meaden

回答:


70

これを実現するための優れた方法はたくさんありますが、他の人はすでに提案しています。「SQLトラックを介してExcelデータを取得する」に続いて、ここにいくつかの指針があります。

  1. Excelには「データ接続ウィザード」があり、別のデータソースから、またはまったく同じExcelファイル内でもインポートまたはリンクできます。

  2. Microsoft Office(およびOS)の一部として、関心のある2つのプロバイダーがあります。古い「Microsoft.Jet.OLEDB」と最新の「Microsoft.ACE.OLEDB」です。接続を設定するとき(データ接続ウィザードなど)にそれらを探します。

  3. Excelブックに接続すると、ワークシートまたは範囲はテーブルまたはビューに相当します。ワークシートのテーブル名は、ドル記号( "$")が追加され、角括弧( "["および "]")で囲まれたワークシートの名前です。範囲の、それは単に範囲の名前です。名前のないセル範囲をレコードソースとして指定するには、角括弧内のシート名の最後に標準のExcelの行/列表記を追加します。

  4. ネイティブSQLは(多かれ少なかれ)MicrosoftAccessのSQLになります。(以前はJET SQLと呼ばれていましたが、Access SQLは進化しており、JETは廃止された古い技術だと思います。)

  5. ワークシートを読む例: SELECT * FROM [Sheet1$]

  6. 例、範囲の読み取り: SELECT * FROM MyRange

  7. 例、名前のないセル範囲の読み取り: SELECT * FROM [Sheet1$A1:B10]

  8. あなたが詳細を処理するのを助けるために利用できる多くの多くの本とウェブサイトがあります。

===その他の注意事項===

デフォルトでは、Excelデータソースの最初の行に、フィールド名として使用できる列見出しが含まれていると想定されています。そうでない場合は、この設定をオフにする必要があります。そうしないと、データの最初の行が「消えて」フィールド名として使用されます。これはHDR= setting、接続文字列の拡張プロパティにオプションを追加することによって行われます。指定する必要のないデフォルトはHDR=Yesです。列見出しがない場合は、HDR=No;を指定する必要があります。プロバイダーは、フィールドにF1、F2などの名前を付けます。

ワークシートの指定に関する注意:プロバイダーは、データのテーブルが、指定されたワークシートの最上部、左端、空白でないセルで始まると想定しています。つまり、データのテーブルは、行3、列Cから問題なく開始できます。ただし、たとえば、セルA1のデータの左上にワークシートのタイトルを入力することはできません。

範囲の指定に関する注意:ワークシートをレコードソースとして指定すると、スペースが許す限り、プロバイダーはワークシートの既存のレコードの下に新しいレコードを追加します。範囲(名前付きまたは名前なし)を指定すると、Jetは、スペースが許す限り、範囲内の既存のレコードの下に新しいレコードも追加します。ただし、元の範囲で再クエリを実行すると、結果のレコードセットには、範囲外で新しく追加されたレコードは含まれません。

Cのデータ型(試す価値があります)REATE TABLE: Short, Long, Single, Double, Currency, DateTime, Bit, Byte, GUID, BigBinary, LongBinary, VarBinary, LongText, VarChar, Decimal

「古い技術」のExcel(xls拡張子を持つファイル)への接続:Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyFolder\MyWorkbook.xls;Extended Properties=Excel 8.0;。Microsoft Excel 5.0および7.0(95)ブックにはExcel 5.0ソースデータベースタイプを使用し、Microsoft Excel 8.0(97)、9.0(2000)および10.0(2002)ブックにはExcel8.0ソースデータベースタイプを使用します。

「最新の」Excel(xlsxファイル拡張子を持つファイル)への接続: Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Excel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;"

データをテキストとして扱う:IMEX設定は、すべてのデータをテキストとして扱います。 Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Excel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";

(詳細については、http://www.connectionstrings.com/excelを参照してください

詳細については、http://msdn.microsoft.com/en-US/library/ms141683(v = sql.90).aspxおよびhttp://support.microsoft.com/kb/316934参照してください。

http://support.microsoft.com/kb/257819で詳しく説明されているVBAを介したADODBを介したExcelへの接続

Microsoft JET 4の詳細(http://support.microsoft.com/kb/275561)


4
データ接続にはファイル名が必要です。これは、タスクが現在のファイルを照会する場合のショーストッパーです。さらに、クエリは数式と同じように使用することはできません。範囲を設定するには、固定クエリのみを使用できます。自動的には更新されません。したがって、現在のファイルをクエリすることはできず、数式のドロップイン置換として使用することもできません。
ivan_pozdeev 2018

2
@ivan_pozdeev Excel 2010を使用して、現在のファイルをクエリできることを確認しました。Excel / Officeの新しいエディションでこれが不可能になるかどうかはわかりません。データ接続ウィザードを使用して自己参照テーブルを作成するのは不格好であることに同意します。これは主に、ワークブックへのフルパスを使用して接続が行われるため、ワークブックの名前を変更/コピー/移動すると、ブックが壊れたり、結果が混乱したりする可能性があるためです。ただし、VBAの使用が問題にならないワークブックの場合、自己参照クエリは非常に管理しやすくなります。
rskar 2018

@ivan_pozdeevまた、Excelが自己参照テーブルを自動更新するように最適化されていないことにも同意します。推定は常に外部から供給されたデータです。自動更新は、接続プロパティの[使用状況]タブを介して可能であり(非常に多くの分ごとにリロードする場合など)、VBAを使用すると再計算イベントを利用できます。それでも、フォーミュラのドロップイン代替品としてこれを売り過ぎたとは思わない。
rskar 2018

2
「これを実現するための優れた方法はたくさんあります」-要求されたユースケースに対してこれらすべての「優れた」方法が実際に持っている大きな欠陥(それそれらの広範な使用を妨げるもの)を理解していない場合、私何であるかわかりません。
ivan_pozdeev 2018

8

tl; dr; Excelはこれらすべてをネイティブに実行します-フィルターテーブルを使用します

http://office.microsoft.com/en-gb/excel-help/filter-data-in-an-excel-table-HA102840028.aspx

oledb接続を介してプログラムでExcelを開き、ワークシート内のテーブルでSQLを実行できます。

しかし、数式を使わずに、フィルターだけで、求めているすべてのことを実行できます。

  1. データ内の任意の場所をクリックし、あなたが見ています
  2. リボンバーのデータに移動します
  3. 真ん中あたりで「フィルター」を選択すると、じょうごのように見えます
    • これで、テーブルの最初の行の各セルのタイトな側に矢印が表示されます。
  4. 電話番号の矢印をクリックして、空白の選択を解除します(最後のオプション)
  5. 姓の矢印をクリックして、azの順序選択します(トップオプション)

遊んでください..注意すべきいくつかの事柄:

  1. フィルタリングされた行を選択して、別の場所に貼り付けることができます
  2. 左側のステータスバーに、行の総数からフィルター基準を満たす行の数が表示されます。(例:313レコード中308レコードが見つかりました)
  3. ワードのExcel2010で色でフィルタリングできます
  4. 時々私はデータのステータスまたはクリーンアップされたバージョンを与える計算列を作成し、それらによってフィルタリングまたはソートすることもできます。(例えば、他の回答の式のように)

頻繁に行う場合や、どこかでデータのインポートを自動化したい場合を除いて、フィルターを使用して行います。ただし、完全を期すために:

C#オプション:

 OleDbConnection ExcelFile = new OleDbConnection( String.Format( "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;HDR=YES\"", filename));
 ExcelFile.Open();

開始するのに便利な場所は、スキーマを確認することです。考えているよりも多くのスキーマがある可能性があるためです。

List<String> excelSheets = new List<string>();

// Add the sheet name to the string array.
foreach (DataRow row in dt.Rows) {
    string temp = row["TABLE_NAME"].ToString();
    if (temp[temp.Length - 1] == '$') {
         excelSheets.Add(row["TABLE_NAME"].ToString());
    }
}

次に、シートをクエリする場合:

 OleDbDataAdapter da = new OleDbDataAdapter("select * from [" + sheet + "]", ExcelFile);
 dt = new DataTable();
  da.Fill(dt);

注-Excelでテーブルを使用してください!:

Excelには、データをテーブルのように動作させる「テーブル」機能があります。これにより、いくつかの大きな利点が得られますが、すべての種類のクエリを実行できるわけではありません。

http://office.microsoft.com/en-gb/excel-help/overview-of-excel-tables-HA010048546.aspx

Excelの表形式のデータの場合、これが私のデフォルトです。最初に行うことは、データをクリックして、リボンのホームセクションから[テーブルとしてフォーマット]を選択することです。これにより、デフォルトでフィルタリングと並べ替えが可能になり、名前(table [fieldname]など)でテーブルとフィールドにアクセスできるようになります。これにより、maxやaverageなどの列の集計関数も可能になります。


列を減らしたい場合は、個人的にフィルタリングされた行を新しいシートにコピーし、不要な列を削除します。あなたはそれらを隠すことができますが、それだけの価値はめったにありません。

1
using System.Data.OleDb; using System.Data;

1
私は毎日フィルターをかけ、C#で週に数回スプレッドシートにアクセスしています。C#を使用する場合、データをデータベースにインポートして実際に操作する傾向があります。データがSQLサーバーに配置された後、フィルターまたはSQLのいずれかを実際にクエリする場合は、中間SQLでExcelレベルで実行する価値はありません。

7

これは、次のようにネイティブに実行できます。

  1. テーブルを選択し、Excelを使用して姓で並べ替えます
  2. たとえば、E1とE2で、2行1列の高度なフィルター基準を作成します。E1は空で、E2には、=C6="" C6が電話番号列の最初のデータセルである数式が含まれています。
  3. テーブルを選択して高度なフィルターを使用し、E1:E2の基準範囲を使用して範囲にコピーし、出力をコピーする場所を指定します

これをプログラムで実行する場合は、マクロレコーダーを使用して上記の手順を記録し、コードを確認することをお勧めします。


8
質問はSQLを指定します。
S Meaden 2018年

4

あなたはできるExcelでSQLを使用します。それはよく隠されているだけです。このチュートリアルを参照してください:

http://smallbusiness.chron.com/use-sql-statements-ms-excel-41193.html


3
SQLを使用してExcelにインポートするデータを選択しているように見えますが、現在のスプレッドシートに対してクエリを実行していませんか?
Rup 2016

Excelで(名前マネージャーで)各テーブルの名前を作成するか、テーブルを選択してセルアドレスが表示されているボックスに名前を入力するだけです。次に、それを使用してワークシートに対してクエリを実行できます。クエリではシートの完全なアドレスを取得しているため、スプレッドシートをディスク上の別の場所に移動すると、クエリは機能しません
Petrik 2017年

3

QueryStormを提供することを勧めしますを試してみるします。これはExcelのプラグインであり、ExcelでSQLを使用するのに非常に便利です。

また、それはフリーミアムです。オートコンプリートやエラーの波線などを気にしない場合は、無料で使用できます。ダウンロードしてインストールするだけで、ExcelでSQLがサポートされます。

免責事項:私は著者です。


1
残念ながら、これは優れたツールですが、30日間の試用期間を除いて、現在は有料のようです。
マーク

2

一度これを行う必要がある場合は、Charlesの説明に従ってください。ただし、フィルターを動的にしたい場合は、Excelの数式とヘルパー列を使用してこれを行うこともできます。

データがシートDataSheetにあり、次の列の行2から始まると仮定します。

  • A:姓
  • B:名
  • C:電話番号

このシートには2つのヘルパー列が必要です。

  • D2 :=if(A2 = "", 1, 0)、これはフィルター列であり、where条件に対応します
  • E2 :=if(D2 <> 1, "", sumifs(D$2:D$1048576, A$2:A$1048576, "<"&A2) + sumifs(D$2:D2, A$2:A2, A2))、これは次の順序に対応します

データが入る限り、これらの数式をコピーしてください。

結果を表示するシートに、次の列を作成します。

  • A:行2の1から始まる一連の数字。これにより、取得できる行の総数が制限されます(続編の制限のようなものです)
  • B2 :=match(A2, DataSheet!$E$2:$E$1048576, 0)、これは対応するデータの行です
  • C2 :=iferror(index(DataSheet!A$2:A$1048576, $B2), "")、これは実際のデータであり、データが存在しない場合は空です

B2とC2の数式をコピーし、列CをDとEにコピーして貼り付けます。


0

Excelファイルを直接クエリする場合は、esProcを試してください。https://esprocforbp.medium.com/directly-query-excel-text-files-using-sql-5315788231e4を参照してください。通常のSQLをサポートするだけでなく、グループHAVING、サブクエリ、ネストされたサブクエリ、結合、さらには 'with…as'テーブル式もサポートします。例:

$with A as
(select NAME as DEPT from E:/department.xlsx where NAME='HR' or NAME='Sales') 
select A.DEPT DEPT,count(*) NUM,avg(B.SAL_ARY) AVG_SALARY from A left join E:/employee.xlsx B on A.DEPT=B.DEPT
where B.GENDER='F' group by A.DEPT

Excelで領域をクエリする場合は、データをクリップボードにコピーします。次に、esProcはクリップボード関数にアクセスしてデータテーブルを取得し、単一テーブルのクエリを実行します。複数の領域をクエリする場合は、データの各領域をesProcにコピーし、esProcで複数のテーブルを取得して、例のように複数テーブルのクエリを実行します。

免責事項:これは私たちのツールesProcについてです。フリーミアムです。


-1

選択した言語/プラットフォームでExcel用のネイティブDBドライバーを試すことができます。Javaの世界では、Excelシートを直接操作するためのJDBCドライバーを提供するhttp://code.google.com/p/sqlsheet/を試すことができます。同様に、他のプラットフォーム用のDBテクノロジーのドライバーを入手できます。

ただし、これらのラッパーライブラリが提供する機能の数ですぐに壁にぶつかることを保証できます。より良い方法は、Apache HSSF / POIまたは同様のレベルのライブラリを使用することですが、より多くのコーディング作業が必要になります。


-1

私は誤解しているかもしれませんが、これはまさにピボットテーブルが行うことではありませんか?テーブルにデータがありますか、それともフィルタリングされたリストだけですか?テーブルでない場合は1つ(ctrl + 1)にし、テーブル内の任意のセルをアクティブにして、別のシートにピボットテーブルを挿入します。次に、列lastname、firstname、phonenumberをrowsセクションに追加します。次に、電話番号をフィルターセクションに追加し、null値をフィルターで除外します。通常のように並べ替えます。



-1

あなたが持っている場合はGDAL / OGR Expatのライブラリとしてコンパイルし、あなたが使用することができXLSXドライバをの.xlsxファイルを読むために、そしてプロンプトコマンドからSQL式を実行します。たとえば、スプレッドシートと同じディレクトリにあるosgeo4wシェルから、ogrinfoユーティリティを使用します。

ogrinfo -dialect sqlite -sql "SELECT name, count(*) FROM sheet1 GROUP BY name" Book1.xlsx

SQLiteクエリを実行しsheet1、クエリ結果を通常とは異なる形式で出力します。

INFO: Open of `Book1.xlsx'
      using driver `XLSX' successful.

Layer name: SELECT
Geometry: None
Feature Count: 36
Layer SRS WKT:
(unknown)
name: String (0.0)
count(*): Integer (0.0)
OGRFeature(SELECT):0
  name (String) = Red
  count(*) (Integer) = 849

OGRFeature(SELECT):1
  name (String) = Green
  count(*) (Integer) = 265
...

または、ogr2ogrを使用して同じクエリを実行し、単純なCSVファイルを作成します。

$ ogr2ogr -f CSV out.csv -dialect sqlite \
          -sql "SELECT name, count(*) FROM sheet1 GROUP BY name" Book1.xlsx

$ cat out.csv
name,count(*)
Red,849
Green,265
...

古い.xlsファイルで同様のことを行うには、FreeXLライブラリに対して構築されたXLSドライバーが必要になりますが、これは実際には一般的ではありません(たとえば、OSGeo4wからではありません)。


-2

MicrosoftAccessとLibreOfficeBaseは、スプレッドシートをソースとして開き、SQLクエリを実行できます。これは、あらゆる種類のクエリを実行し、マクロの実行やコードの記述の混乱を回避するための最も簡単な方法です。

Excelには、例のような多くの単純なクエリを実行するオートフィルターとデータ並べ替えもあります。これらの機能についてサポートが必要な場合は、Googleが私よりも優れたチュートリアルのソースになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.