SQL转矩阵<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />大家好,
是否可以将数据库中的数据直接提取到矩阵中而无需先将其导入数据表?
谢谢!
回复:SQL 到矩阵感谢您的评论。
我有一个庞大的信用卡公司数据库数据集,大约有一百万用户,每个用户都有几千个观察结果。
我一次下载每个用户并分析他的行为模式(这是大 for 循环)。
当我一次手动运行一个用户时,它运行良好。 当运行超过 20 个用户时,它会在没有任何解释的情况下随机崩溃(程序刚刚关闭,或者我得到“jmp 执行了访问冲突”)。我在鲁棒性方面不断改进我的命令,但仍然试图找到最薄弱的环节。
罗恩
回复:SQL 到矩阵我忘了提一下,使用 'Select *' 肯定会降低查询性能。在 for 循环中使用它是死刑。永远不要在 SQL 中偷懒,输入所有要提取的列,即使是表中的每一列。你会看到你的代码运行得更快了。
回复:SQL 到矩阵非常感谢您,
现在我的脚本运行得更快并且问题更少。
罗恩
回复:SQL 到矩阵是的,你需要 eval 插入,我没想到。
回复:SQL 到矩阵您确实需要 evalinsert ,因为您每次都在通过循环评估 i 。
回复:SQL 到矩阵谢谢你,
这很有帮助!
我的 SQL 语句只是我从手动打开表中复制的粗略脚本。
我想我设法得到了大部分,除了 Eval Insert。 没有它我该怎么办?
这是我当前的脚本。
数据库连接=创建数据库连接(
"DBQ=D:\MY DOCUMENTS\;DefaultDir=D:\MY DOCUMENTS\;Driver={Microsoft 文本驱动程序 (*.txt;*.csv)};DriverId=27;FIL=text;FILEDSN=D:\My Documents\SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Yes;"
) ;
// 在矩阵中提取用户 ID 号:
用户矩阵= ( dt100 =执行 SQL (数据库连接, “从 data.csv 中选择不同的用户 ID” , “dt10 - 用户 ID 列表” ,无形的)) <<得到矩阵;
关( dt100 ,不保存) ;
sqlstr = “选择 * FROM data.csv 其中用户 ID = ^id^” ;
为了(一世= 1 ,一世<= N行(用户矩阵) ,一世++,
ID =用户矩阵[一世] ;
dt10i =执行 SQL (数据库连接,
评估插入( sqlstr ) ,
“用户数据记录” ||字符(一世) || “——” ||字符( ID ) ,无形的) ;
// 分析数据表 //
关( dt10i ,没有保存) ;
) ;
关闭数据库连接(数据库连接) ;
回复:SQL 到矩阵几件事。
首先,将您的第一个查询更改为“SELECT DISTINCT UserId From dataset.csv”;
这做了两件事,使您的查询更快,而且由于您将其作为矩阵拉取,Usermatrix 现在将 = UniqueID 切割几行代码。 这消除了存储未使用的可能非常大的列表和矩阵(用户列表/用户矩阵)的需要。只是但一定要在 for 循环中将 nitems 更改为 nrows。
其次,不需要每次都在 for 循环中建立数据库连接。使用 dbconnection = 创建数据库连接(dsn);其中 dsn 是您上面的长查询字符串。然后将 Open Database(...) 更改为 Execute SQL(dbconnection, sqlstr, "Log Data User " || Char(i), invisible)。
有几点可以从中受益,您将节省每次连接到数据库的时间(这应该会节省很多时间)。您不需要 eval insert() sqlstr,这没什么大不了的,但少了一步。 最后,也很重要的是,不可见地打开 dt10i 将节省大量内存空间,帮助您的代码运行得更快。特别是如果您在“执行分析”部分操作数据表。我看到你最终还是关闭了它。要使脚本运行得更快,请务必记住,您计划关闭的任何数据表都应该以不可见或私有模式打开。
确保有一个关闭数据库连接(数据库连接);在您的代码末尾。
回复:SQL 到矩阵谢谢msharp,
也许我之前应该分享过我的脚本。
欢迎任何建议。
用户矩阵= ( dt100 =开放数据库(
"DBQ=D:\MY DOCUMENTS;DefaultDir=D:\MY DOCUMENTS;Driver={Microsoft 文本驱动程序 (*.txt; *.csv)};DriverId=27;FIL=text;FILEDSN=D:\My Documents\ SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Yes;" ,
// 下一行将只从数据集中提取 UserId 以减少内存使用。
“从 dataset.csv 中选择用户 ID” ,
“dt10 - 用户 ID 列表” ,
无形的
// 私有 // 这个选项不起作用!!!
)) <<得到矩阵;
关( dt100 ,不保存) ;
// 识别用户和他们的ID号
用户列表=关联数组(用户矩阵) ;
唯一身份=用户列表<<获取密钥;
//
// 这只是字符串中的一个语句
sqlstr = “选择 * FROM dataset.csv 其中 id = ^i^” ;
// 循环遍历数据集并一次提取一个单独的数据。
为了(一世= 1 ,一世<= N 项(唯一身份) ,一世++,
// 使用语句为每个用户提取个人日志。
dt10i =开放数据库(
"DBQ=D:\MY DOCUMENTS;DefaultDir=D:\MY DOCUMENTS;Driver={Microsoft 文本驱动程序 (*.txt; *.csv)};DriverId=27;FIL=text;FILEDSN=D:\My Documents\ SQLLog Data.dsn;MaxBufferSize=2048;MaxScanRows=8;PageTimeout=5;SafeTransactions=0;Threads=3;UID=admin;UserCommitSync=Yes;" ,
评估插入( sqlstr ) ,
“日志数据用户” ||字符(一世) ,
) ;
// 执行分析 ...//
关( dt10i ,没有保存) ;
) ;
回复:SQL 到矩阵听起来你可以优化你的 SQL 语句。
就像是:
使用 IDtemp 作为(从 IDtable 中选择 IDcol,其中 IDcol = 'FilterCriteria')
从 IDtable 中选择 *
内连接 IDtemp
这将首先创建一个临时 IDtemp 表,SQL 使用该表来加入更大的 IDtable。内连接大大减少了 SQL 必须处理的表的大小。当然,可能有更简单的方法可以让它更快。一切都取决于数据的存储方式和表的大小。
我将专注于优化您的 SQL 语句,而不是优化 JMP 交互和提取数据的方式。
回复:SQL 到矩阵谢谢msharp,
这让我更清楚我没有错过任何东西。
问题是数据源很大,我只需要获取 ID 列表(一列)。 之后,我为每个 ID 提取数据(许多列)并分别分析。打开整个数据集是不可行的。
罗恩
回复:SQL 到矩阵嗯,是的,也不是。您可以使用以下命令将其作为矩阵直接导入 JSL:
matrix = 执行 SQL(dsn, sql_string, table_name, invisible) << 获取矩阵;
但是,执行 SQL 语句仍然会创建一个数据表。 如果“私有”是一个选项,那么它是可能的,因为如果私有数据表没有存储在某个地方,JMP 会自动从您的计算机内存中清除它们。 唉,隐形是他们给我们的最好的。
您可以使用以下脚本关闭不可见表。在所有实用性中,它会一样快,因为执行 SQL 语句将始终是瓶颈。
matrix = (dt = Execute SQL(dsn, sql_string, table_name, invisible)) << 获取矩阵;
关闭(dt);