简体   繁体   English

SQL Microsoft Access

[英]SQL Microsoft Access

I have a table of transactions in Microsoft Access that contains many transactions for many vendors. 我在Microsoft Access中有一个事务表,其中包含许多供应商的许多事务。 I need to identify if there is sequential transaction numbering for each vendor. 我需要确定每个供应商是否有顺序的交易编号。 I don't know what the sequence will be or the number of transactions per vendor. 我不知道顺序是什么,也不知道每个供应商的交易数量。 I need to write a SQL that identifies sequential numbering for vendors and sets a field to '1' if present. 我需要编写一个SQL,该SQL标识供应商的顺序编号,并将字段设置为“ 1”(如果存在)。 I was thinking of running nested loops that first determine number of transactions per vendor then loops through those transactions comparing the transaction numbers. 我正在考虑运行嵌套循环,该循环首先确定每个供应商的交易数量,然后循环比较那些交易数量的交易。 Can anybody help me with this?? 有人可以帮我吗?

To find one sequential set (2 records where one transaction number follows the other): 查找一个顺序集(2个记录,其中一个事务编号紧跟另一个事务编号):

SELECT transactionId FROM tbl WHERE EXISTS 
  (SELECT * FROM tbl as t WHERE tbl.vendorId = t.vendorId 
   AND tbl.transactionId+1 = t.transactionId)

I would use a query that finds gaps in numbering for any vendor, and if that returns any records, then you do not have sequential numbering for all vendors. 我将使用一个查询来查找任何供应商的编号间隔,如果返回任何记录,则您没有针对所有供应商的顺序编号。

SELECT *
FROM tblTransaction As T1
WHERE (
    SELECT TOP 1 T2.transactionID
    FROM tblTransaction As T2
    WHERE T1.vendorID = T2.vendorID AND
          T1.transactionID < T2.transactionID
    ORDER BY T2.transactionID
) - T1.transactionID > 1

What this does is, for each record in the table, look for the lowest-numbered other transactionID in the same table that is for the same vendor and has a higher-numbered transactionID than the first one. 这样做是针对表中的每个记录,在同一表中查找同一供应商的编号最小的其他transactionID,该编号比第一个具有更大的transactionID。 If that the transactionID value of that record is more than one higher than the value in the first record, that represents a gap in numbering for the vendor. 如果该记录的transactionID值比第一条记录的值高一个以上,则表示供应商的编号存在差异。

Edit: Changed variable names above as requested. 编辑:根据要求更改了上面的变量名称。

I'm not sure this is the most straightforward approach but I think it could work. 我不确定这是否是最直接的方法,但我认为它可能有效。 Apologies for using multiple steps but Jet 4.0 kind of forces one to do so.** 为使用多个步骤而道歉,但是Jet 4.0迫使这样做。**

I've assumed all transactionId values are positive integers and that a sequence is a set of evenly spaced transactionId values by vendorId . 我假定所有transactionId值都是正整数,并且序列是vendorId一组均匀间隔的transactionId值。 I further assume there is a key on (vendorId, transactionId) . 我进一步假设在(vendorId, transactionId)上有一个键。

First step, elmininate invalid rows eg need at least three rows to be able to determine a sequence (do all other rows pass or fail?); 第一步,消除无效的行,例如,至少需要三行才能确定顺序(所有其他行通过还是失败?); may want to filter other junk out here too (eg rows/groups with NULL values): 可能也想在这里过滤掉其他垃圾(例如,具有NULL值的行/组):

CREATE VIEW tbl1
AS
SELECT T1.vendorId, T1.transactionId
  FROM tbl AS T1
 WHERE EXISTS (
               SELECT T2.vendorId
                 FROM tbl AS T2
                WHERE T2.vendorId = T1.vendorId
                GROUP 
                   BY T2.vendorId
                HAVING COUNT(*) > 2
              );

Find the lowest value for each vendor (comes in handy later): 查找每个供应商的最小值(稍后派上用场):

CREATE VIEW tbl2
AS
SELECT vendorId, MIN(transactionId) AS transactionId_min
  FROM tbl1
 GROUP 
    BY vendorId;

Make all sequences start at zero ( transactionId_base_zero ) by subtracting the lowest value for each vendor: 通过减去每个供应商的最小值,使所有序列都从零开始( transactionId_base_zero ):

CREATE VIEW tbl3
AS
SELECT T1.vendorId, T1.transactionId, 
       T1.transactionId - T2.transactionId_min AS transactionId_base_zero
  FROM tbl1 AS T1
       INNER JOIN tbl2 AS T2
          ON T1.vendorId = T2.vendorId;

Predict the step value (difference between adjacent sequence values) based on the MAX , MIN and COUNT set values for each vendor: 根据每个供应商的MAXMINCOUNT设置值预测步长值(相邻序列值之间的差异):

CREATE VIEW tbl4
AS
SELECT vendorId, 
       MAX(transactionId_base_zero) / (COUNT(*) - 1)
          AS transactionId_predicted_step
  FROM tbl3;

Test that the predicted step value hold true for each squence value ie (pseudo code) this_transactionId - step_value = prior_transactionId (omit the lowest transactionId because it doesn't have a prior value!): 测试每个步长值的预测步长值是否都正确,即(伪代码) this_transactionId - step_value = prior_transactionId (省略最低的transactionId因为它没有先验值!):

SELECT DISTINCT T.vendorId
  FROM tbl3 AS T
 WHERE T.transactionId_base_zero > 0
       AND NOT EXISTS (
                       SELECT *
                         FROM tbl3 AS T3
                              INNER JOIN tbl4 AS T4
                                 ON T3.vendorId = T4.vendorId      
                        WHERE T.vendorId = T3.vendorId
                              AND T.transactionId_base_zero 
                                     - T4.transactionId_predicted_step 
                                        = T3.transactionId_base_zero
                      );

The above query should return the vendorId of vendors whose transactionId values are not sequential. 上面的查询应返回其transactionId值不连续的供应商的vendorId


** In my defense, I ran into a couple of bugs Jet 4.0 I had to code around workaround. **在我的辩护中,我遇到了两个必须围绕变通办法编写代码的Jet 4.0错误。 Yes, I do know the bugs are in Jet 4.0 (or its OLE DB provider) because a) I double checked results using SQL Server and b) they defy logic! 是的,我确实知道这些错误存在于Jet 4.0(或其OLE DB提供程序)中,因为a)我使用SQL Server仔细检查了结果,b)它们违反了逻辑! (even SQL's own strange 3VL logic :) (甚至SQL自己奇怪的3VL逻辑:)

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

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