简体   繁体   English

如何在 Excel 表上运行 SQL 查询?

[英]How to run a SQL query on an Excel table?

I'm trying to create a sub-table from another table of all the last name fields sorted AZ which have a phone number field that isn't null.我正在尝试从另一个表中创建一个子表,该表包含所有按 AZ 排序的姓氏字段,这些字段的电话号码字段不为空。 I could do this pretty easy with SQL, but I have no clue how to go about running a SQL query within Excel.我可以用 SQL 很容易地做到这一点,但我不知道如何在 Excel 中运行 SQL 查询。 I'm tempted to import the data into postgresql and just query it there, but that seems a little excessive.我很想将数据导入 postgresql 并在那里查询,但这似乎有点过分。

For what I'm trying to do, the SQL query SELECT lastname, firstname, phonenumber WHERE phonenumber IS NOT NULL ORDER BY lastname would do the trick.对于我正在尝试做的事情,SQL 查询SELECT lastname, firstname, phonenumber WHERE phonenumber IS NOT NULL ORDER BY lastname可以解决问题。 It seems too simple for it to be something that Excel can't do natively. Excel本身无法做到的事情似乎太简单了。 How can I run a SQL query like this from within Excel?如何从 Excel 中运行这样的 SQL 查询?

There are many fine ways to get this done, which others have already suggestioned.有很多很好的方法可以做到这一点,其他人已经提出了建议。 Following along the "get Excel data via SQL track", here are some pointers.继“通过 SQL 获取 Excel 数据”之后,这里有一些提示。

  1. Excel has the "Data Connection Wizard" which allows you to import or link from another data source or even within the very same Excel file. Excel 具有“数据连接向导” ,它允许您从另一个数据源或什至在同一个 Excel 文件中导入或链接。

  2. As part of Microsoft Office (and OS's) are two providers of interest: the old "Microsoft.Jet.OLEDB", and the latest "Microsoft.ACE.OLEDB".作为 Microsoft Office(和操作系统)的一部分,有两个感兴趣的提供商:旧的“Microsoft.Jet.OLEDB”和最新的“Microsoft.ACE.OLEDB”。 Look for them when setting up a connection (such as with the Data Connection Wizard).在设置连接时查找它们(例如使用数据连接向导)。

  3. Once connected to an Excel workbook, a worksheet or range is the equivalent of a table or view.一旦连接到 Excel 工作簿,工作表或区域就相当于表格或视图。 The table name of a worksheet is the name of the worksheet with a dollar sign ("$") appended to it, and surrounded with square brackets ("[" and "]");工作表的表名是工作表的名称加上美元符号(“$”),并用方括号(“[”和“]”)括起来; of a range, it is simply the name of the range.的范围,它只是范围的名称。 To specify an unnamed range of cells as your recordsource, append standard Excel row/column notation to the end of the sheet name in the square brackets.要将未命名的单元格范围指定为记录源,请将标准 Excel 行/列符号附加到方括号中工作表名称的末尾。

  4. The native SQL will (more or less be) the SQL of Microsoft Access.本机 SQL 将(或多或少)是 Microsoft Access 的 SQL。 (In the past, it was called JET SQL; however Access SQL has evolved, and I believe JET is deprecated old tech.) (过去,它被称为 JET SQL;但是 Access SQL 已经发展,我相信 JET 是不推荐使用的旧技术。)

  5. Example, reading a worksheet: SELECT * FROM [Sheet1$]示例,读取工作表: SELECT * FROM [Sheet1$]

  6. Example, reading a range: SELECT * FROM MyRange示例,读取范围: SELECT * FROM MyRange

  7. Example, reading an unnamed range of cells: SELECT * FROM [Sheet1$A1:B10]例如,读取未命名的单元格区域: SELECT * FROM [Sheet1$A1:B10]

  8. There are many many many books and web sites available to help you work through the particulars.有许多书籍和网站可以帮助您完成这些细节。

Further notes补充说明

By default, it is assumed that the first row of your Excel data source contains column headings that can be used as field names.默认情况下,假定 Excel 数据源的第一行包含可用作字段名称的列标题。 If this is not the case, you must turn this setting off, or your first row of data "disappears" to be used as field names.如果不是这种情况,您必须关闭此设置,否则您的第一行数据将“消失”以用作字段名称。 This is done by adding the optional HDR= setting to the Extended Properties of the connection string.这是通过将可选的HDR= setting添加到连接字符串的扩展属性来完成的。 The default, which does not need to be specified, is HDR=Yes .不需要指定的默认值是HDR=Yes If you do not have column headings, you need to specify HDR=No ;如果没有列标题,则需要指定HDR=No the provider names your fields F1, F2, etc.提供商将您的字段命名为 F1、F2 等。

A caution about specifying worksheets: The provider assumes that your table of data begins with the upper-most, left-most, non-blank cell on the specified worksheet.指定工作表的注意事项:提供程序假定您的数据表从指定工作表上最上方、最左侧的非空白单元格开始。 In other words, your table of data can begin in Row 3, Column C without a problem.换句话说,您的数据表可以从第 3 行 C 列开始,没有问题。 However, you cannot, for example, type a worksheet title above and to the left of the data in cell A1.但是,例如,您不能在单元格 A1 中数据的上方和左侧键入工作表标题。

A caution about specifying ranges: When you specify a worksheet as your recordsource, the provider adds new records below existing records in the worksheet as space allows.指定范围的注意事项:当您将工作表指定为记录源时,提供者会在空间允许的情况下在工作表中的现有记录下方添加新记录。 When you specify a range (named or unnamed), Jet also adds new records below the existing records in the range as space allows.当您指定一个范围(命名或未命名)时,Jet 还会在空间允许的范围内在现有记录下方添加新记录。 However, if you requery on the original range, the resulting recordset does not include the newly added records outside the range.但是,如果您重新查询原始范围,结果记录集不包括该范围外新添加的记录。

Data types (worth trying) for CREATE TABLE: Short, Long, Single, Double, Currency, DateTime, Bit, Byte, GUID, BigBinary, LongBinary, VarBinary, LongText, VarChar, Decimal . CREATE TABLE: Short, Long, Single, Double, Currency, DateTime, Bit, Byte, GUID, BigBinary, LongBinary, VarBinary, LongText, VarChar, Decimal数据类型(值得一试) CREATE TABLE: Short, Long, Single, Double, Currency, DateTime, Bit, Byte, GUID, BigBinary, LongBinary, VarBinary, LongText, VarChar, Decimal

Connecting to "old tech" Excel (files with the xls extention): Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\MyFolder\\MyWorkbook.xls;Extended Properties=Excel 8.0;连接到“旧技术”Excel(扩展名为 xls 的文件): Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\MyFolder\\MyWorkbook.xls;Extended Properties=Excel 8.0; . . Use the Excel 5.0 source database type for Microsoft Excel 5.0 and 7.0 (95) workbooks and use the Excel 8.0 source database type for Microsoft Excel 8.0 (97), 9.0 (2000) and 10.0 (2002) workbooks.将 Excel 5.0 源数据库类型用于 Microsoft Excel 5.0 和 7.0 (95) 工作簿,将 Excel 8.0 源数据库类型用于 Microsoft Excel 8.0 (97)、9.0 (2000) 和 10.0 (2002) 工作簿。

Connecting to "latest" Excel (files with the xlsx file extension): Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Excel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;"连接到“最新”Excel(文件扩展名为 xlsx 的文件): Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Excel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;"

Treating data as text: IMEX setting treats all data as text.将数据视为文本:IMEX 设置将所有数据视为文本。 Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Excel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";

(More details at http://www.connectionstrings.com/excel ) (更多详情请访问http://www.connectionstrings.com/excel

More information athttp://msdn.microsoft.com/en-US/library/ms141683(v=sql.90).aspx , and at http://support.microsoft.com/kb/316934更多信息请访问http://msdn.microsoft.com/en-US/library/ms141683(v=sql.90).aspxhttp://support.microsoft.com/kb/316934

Connecting to Excel via ADODB via VBA detailed at http://support.microsoft.com/kb/257819通过 ADODB 通过 VBA 连接到 Excel,详情见http://support.microsoft.com/kb/257819

Microsoft JET 4 details at http://support.microsoft.com/kb/275561 Microsoft JET 4 详细信息,请访问http://support.microsoft.com/kb/275561

tl;dr; tl;博士; Excel does all of this natively - use filters and or tables Excel 本身就完成了所有这些工作 - 使用过滤器和/或表格

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

You can open excel programatically through an oledb connection and execute SQL on the tables within the worksheet.您可以通过 oledb 连接以编程方式打开 excel 并在工作表中的表上执行 SQL。

But you can do everything you are asking to do with no formulas just filters.但是你可以做任何你要求做的事情,没有公式,只有过滤器。

  1. click anywhere within the data you are looking at单击您正在查看的数据中的任意位置
  2. go to data on the ribbon bar转到功能区栏上的数据
  3. select "Filter" its about the middle and looks like a funnel选择“过滤器”它大约在中间,看起来像一个漏斗
    • you will have arrows on the tight hand side of each cell in the the first row of your table now现在,您将在表格第一行中每个单元格的紧手边上有箭头
  4. click the arrow on phone number and de-select blanks (last option)单击电话号码上的箭头并取消选择空格(最后一个选项)
  5. click the arrow on last name and select az ordering (top option)单击姓氏上的箭头并选择 az ordering (顶部选项)

have a play around.. some things to note:玩玩..一些注意事项:

  1. you can select the filtered rows and pasty them somewhere else您可以选择过滤后的行并将它们粘贴到其他地方
  2. in the status bar on the left you will see how many rows meet you filter criteria out of the total number of rows.在左侧的状态栏中,您将看到有多少行符合您从总行数中筛选出的条件。 (eg 308 of 313 records found) (例如找到 313 条记录中的 308 条)
  3. you can filter by color in excel 2010 on wards您可以在 excel 2010 中按颜色过滤病房
  4. Sometimes i create calculated columns that give statuses or cleaned versions of data you can then filter or sort by theses too.有时我会创建计算列,提供状态或清理过的数据版本,然后您也可以按论文过滤或排序。 (eg like the formulae in the other answers) (例如像其他答案中的公式)

DO it with filters unless you are going to do it a lot or you want to automate importing data somewhere or something.. but for completeness:使用过滤器来做它,除非你打算做很多事情或者你想在某处或某处自动导入数据......但为了完整性:

A c# option:一个 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();

a handy place to start is to take a look at the schema as there may be more there than you think:一个方便的起点是查看架构,因为那里可能比您想象的更多:

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());
    }
}

then when you want to query a sheet:那么当你想查询一张表时:

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

NOTE - Use Tables in excel!:注意 - 在 excel 中使用表格!:

Excel has "tables" functionality that make data behave more like a table.. this gives you some great benefits but is not going to let you do every type of query. Excel 具有“表格”功能,可以使数据表现得更像表格。这会给您带来一些好处,但不会让您执行所有类型的查询。

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

For tabular data in excel this is my default.. first thing i do is click into the data then select "format as table" from the home section on the ribbon.对于 excel 中的表格数据,这是我的默认设置。我做的第一件事是单击数据,然后从功能区的主页部分选择“格式为表格”。 this gives you filtering, and sorting by default and allows you to access the table and fields by name (eg table[fieldname] ) this also allows aggregate functions on columns eg max and average这为您提供过滤和默认排序,并允许您按名称访问表和字段(例如 table[fieldname] )这也允许列上的聚合函数,例如 max 和 average

You can do this natively as follows:您可以按以下方式在本机执行此操作:

  1. Select the table and use Excel to sort it on Last Name选择表格并使用 Excel 按姓氏对其进行排序
  2. Create a 2-row by 1-column advanced filter criteria, say in E1 and E2, where E1 is empty and E2 contains the formula =C6="" where C6 is the first data cell of the phone number column.创建一个 2 行 x 1 列的高级筛选条件,例如在 E1 和 E2 中,其中 E1 为空,E2 包含公式=C6=""其中 C6 是电话号码列的第一个数据单元格。
  3. Select the table and use advanced filter, copy to a range, using the criteria range in E1:E2 and specify where you want to copy the output to选择表并使用高级过滤器,复制到一个范围,使用 E1:E2 中的条件范围并指定要将输出复制到的位置

If you want to do this programmatically I suggest you use the Macro Recorder to record the above steps and look at the code.如果您想以编程方式执行此操作,我建议您使用宏记录器记录上述步骤并查看代码。

Might I suggest giving QueryStorm a try - it's a plugin for Excel that makes it quite convenient to use SQL in Excel.我可以建议尝试一下QueryStorm - 它是 Excel 的插件,可以非常方便地在 Excel 中使用 SQL。

Also, it's freemium.此外,它是免费增值服务。 If you don't care about autocomplete, error squigglies etc, you can use it for free.如果你不关心自动完成、错误曲线等,你可以免费使用它。 Just download and install, and you have SQL support in Excel.只需下载并安装,您就可以在 Excel 中获得 SQL 支持。

Disclaimer: I'm the author.免责声明:我是作者。

You can use SQL in Excel.可以在 Excel 中使用 SQL。 It is only well hidden.它只是隐藏得很好。 See this tutorial:请参阅本教程:

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

If you need to do this once just follow Charles' descriptions, but it is also possible to do this with Excel formulas and helper columns in case you want to make the filter dynamic.如果您需要一次执行此操作,只需按照 Charles 的说明进行操作,但也可以使用 Excel 公式和辅助列执行此操作,以防您想使过滤器动态化。

Lets assume you data is on the sheet DataSheet and starts in row 2 of the following columns:假设您的数据位于工作表 DataSheet 上,并从以下列的第 2 行开始:

  • A: lastname答:姓氏
  • B: firstname B:名字
  • C: phonenumber C:电话号码

You need two helper columns on this sheet.您需要此工作表上的两个辅助列。

  • D2: =if(A2 = "", 1, 0) , this is the filter column, corresponding to your where condition 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)) , this corresponds to the order by E2: =if(D2 <> 1, "", sumifs(D$2:D$1048576, A$2:A$1048576, "<"&A2) + sumifs(D$2:D2, A$2:A2, A2)) , 这个对应于 order by

Copy down these formulas as far as your data goes.尽可能复制这些公式。

On the sheet which should display your result create the following columns.在应显示结果的工作表上创建以下列。

  • A: A sequence of numbers starting with 1 in row 2, this limits the total number of rows you can get (kind like a limit in sequel) A:第 2 行以 1 开头的数字序列,这限制了您可以获得的总行数(类似于续集中的限制)
  • B2: =match(A2, DataSheet!$E$2:$E$1048576, 0) , this is the row of the corresponding data B2: =match(A2, DataSheet!$E$2:$E$1048576, 0) ,这是对应数据的行
  • C2: =iferror(index(DataSheet!A$2:A$1048576, $B2), "") , this is the actual data or empty if no data exists C2: =iferror(index(DataSheet!A$2:A$1048576, $B2), "") ,这是实际数据,如果没有数据则为空

Copy down the formulas in B2 and C2 and copy-past column C to D and E.复制 B2 和 C2 中的公式,并将 C 列复制到 D 和 E。

I found great example where you can treat worksheets just like tables. 我找到了一个很好的示例,您可以在其中将工作表像表一样对待。 在此处输入图片说明

video link 影片连结

You can experiment with the native DB driver for Excel in language/platform of your choice.您可以在您选择的语言/平台中试验 Excel 的本机 DB 驱动程序。 In Java world, you can try with http://code.google.com/p/sqlsheet/ which provides a JDBC driver for working with Excel sheets directly.在 Java 世界中,您可以尝试使用http://code.google.com/p/sqlsheet/ ,它提供了用于直接处理 Excel 工作表的 JDBC 驱动程序。 Similarly, you can get drivers for the DB technology for other platforms.同样,您可以为其他平台的 DB 技术获取驱动程序。

However, I can guarantee that you will soon hit a wall with the number of features these wrapper libraries provide.但是,我可以保证您很快就会被这些包装器库提供的​​功能数量所困扰。 Better way will be to use Apache HSSF/POI or similar level of library but it will need more coding effort.更好的方法是使用 Apache HSSF/POI 或类似级别的库,但它需要更多的编码工作。

I might be misunderstanding me, but isn't this exactly what a pivot table does?我可能误解了我的意思,但这不正是数据透视表的作用吗? Do you have the data in a table or just a filtered list?你有表格中的数据还是只是一个过滤列表? If its not a table make it one (ctrl+l) if it is, then simply activate any cell in the table and insert a pivot table on another sheet.如果它不是表格,则将其设为一个 (ctrl+l),然后只需激活表格中的任何单元格并在另一张工作表上插入数据透视表。 Then Add the columns lastname, firstname, phonenumber to the rows section.然后将列姓氏、名字、电话号码添加到行部分。 Then Add Phone number to the filter section and filter out the null values.然后将电话号码添加到过滤器部分并过滤掉空值。 Now Sort like normal.现在排序正常。

I suggest you to have a look at the MySQL csv storage engine which essentially allows you to load any csv file (easily created from excel) into the database, once you have that, you can use any SQL command you want.我建议你看看 MySQL csv 存储引擎,它基本上允许你将任何 csv 文件(很容易从 excel 创建)加载到数据库中,一旦你有了它,你就可以使用任何你想要的 SQL 命令。

It's worth to have a look at it.值得一看。

If you have GDAL/OGR compiled with the against the Expat library, you can use the XLSX driver to read .xlsx files, and run SQL expressions from a command prompt.如果您使用 Expat 库编译了GDAL/OGR ,您可以使用XLSX 驱动程序读取 .xlsx 文件,并从命令提示符运行 SQL 表达式。 For example, from a osgeo4w shell in the same directory as the spreadsheet, use the ogrinfo utility:例如,从与电子表格相同目录中的osgeo4w shell,使用ogrinfo实用程序:

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

will run a SQLite query on sheet1 , and output the query result in an unusual form:将在sheet1上运行SQLite查询,并以不寻常的形式输出查询结果:

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
...

Or run the same query using ogr2ogr to make a simple CSV file:或者使用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
...

To do similar with older .xls files, you would need the XLS driver , built against the FreeXL library, which is not really common (eg not from OSGeo4w).要对较旧的 .xls 文件执行类似操作,您需要针对 FreeXL 库构建的XLS 驱动程序,这并不常见(例如不是来自 OSGeo4w)。

Microsoft Access and LibreOffice Base can open a spreadsheet as a source and run sql queries on it. Microsoft Access 和 LibreOffice Base 可以打开电子表格作为源并在其上运行 sql 查询。 That would be the easiest way to run all kinds of queries, and avoid the mess of running macros or writing code.这将是运行各种查询的最简单方法,并避免运行宏或编写代码的混乱。

Excel also has autofilters and data sorting that will accomplish a lot of simple queries like your example. Excel 还具有自动过滤器和数据排序功能,可以完成许多简单的查询,例如您的示例。 If you need help with those features, Google would be a better source for tutorials than me.如果您需要有关这些功能的帮助,Google 将是比我更好的教程来源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM