在SQL中可以/应该完成多少任务?

时间:2010-02-08 13:11:07

标签: php sql mysql

我有一个数据库,我想构建一个与我的indata匹配的结果。

示例说明: “Indata”是在步骤#1中具有过滤器标准的行,见下文。 “过滤器#1之后的结果”是步骤#1之后留下的行 “过滤器#2之后的结果”是步骤#2之后留下的行 “打印为indata 1”是最终结果,在第二次过滤后显示字段OutData的字段,以及字段“警告”的组合内容

步骤#1。过滤Outdata表以仅保留与Indata匹配的记录。 Star *匹配任何东西。每行必须与indata行匹配。见例子。

步骤#1b。 Indata Depl不直接匹配,但检查在OutData范围内 Depl-DeplOffMin> Indata Depl

第二步。再次过滤Outdata表,仅保留每个Pos的唯一行,选择存在重复项时具有最低不匹配的行。见例子。

第3步。使用唯一的Pos创建Outdata Field的所有可能组合。与LOOP类似:第一个Pos = 10的OutData +第一个Pos = 20的OutData +第一个Pos = 30的OutData +第一个Pos = 30的OutData,请参见示例中的“Print”行。

步骤#4。对输出组合进行排序,即“打印”行,以在顶部具有最低的不匹配。见例子。

你会尝试将其作为一个大的SQL查询,还是构建临时表等,将它与PHP混合进行更多的工作?

(真正的数据库可能是MySQL中的1000个和30个字段.Indata通过Ajax发送到服务器,PHP中的服务器代码生成打印数据并将其发回。)

"Outdata" table, example:

Pos   OutData     Warn  Mismatch    Producer    Depl        DeplOffMax        DeplOffMin  Axis        Connection
10    S                 0           S           *           *                 *                       *           *
20    24                0           S           24          *                 *           *           *
20    24          +-5   5           S           24          5                 -5          *           *
20    24          +-10  10          S           24          10                -10         *           *
20    48                0           S           48          *                 *           *           *
30    AA                0           S           *           *                 *           A           *
30    AB                0           S           *           *                 *           B           *
30    AC                0           S           *           *                 *           C           *
30    AA          B-AA  5           S           *           *                 *           B
40    C1                0           S           *           *                 *           *           C1
40    C1                1           S           *           *                 *           B           *
40    C1                2           S           24          10                -10         *           *
40    C2                0           S           *           *                 *           *           C2





Example 1:
Indat 1:                           S           24                                        A           C2

Result for indata 1 after filter #1:
10    S                 0           S           *           *                 *                       *           *
20    24                0           S           24          *                 *           *           *
20    24          +-5   5           S           24          5                 -5          *           *
20    24          +-10  10          S           24          10                -10         *           *
30    AA                0           S           *           *                 *           A           *
40    C1                2           S           24          10                -10         *           *
40    C2                0           S           *           *                 *           *           C2

Result for indata 1 after filter #2:
10    S                 0           S           *           *                 *                       *           *
20    24                0           S           24          *                 *           *           *
30    AA                0           S           *           *                 *           A           *
40    C1                2           S           24          10                -10         *           *
40    C2                0           S           *           *                 *           *           C2

Print for indata 1:
Mismatch 0:       S 24 AA C2  Warning -
Mismatch 2:       S 24 AA C1  Warning -



Example 2:
Indata 2:                           S           33                                        B           C2

Result for indata 2 after filter #1:
10    S                 0           S           *           *                 *                       *           *
20    24          +-10  10          S           24          10                -10         *           *
30    AB                0           S           *           *                 *           B           *
30    AA          B-AA  5           S           *           *                 *           B
40    C1                1           S           *           *                 *           B           *
40    C1                2           S           24          10                -10         *           *
40    C2                0           S           *           *                 *           *           C2

Result for indata 2 after filter #2:
10    S                 0           S           *           *                 *                       *           *
20    24          +-10  10          S           24          10                -10         *           *
30    AB                0           S           *           *                 *           B           *
30    AA          B-AA  5           S           *           *                 *           B
40    C1                1           S           *           *                 *           B           *
40    C2                0           S           *           *                 *           *           C2

Print for indata 2:
Mismatch 10:      S 24 AB C2  Warning: +-10
Mismatch 11:      S 24 AB C1  Warning: +-10
Mismatch 15:      S 24 AA C2  Warning: +-10 B-AA
Mismatch 16:      S 24 AA C1  Warning: +-10 B-AA





Example 3:
Indata 3:                           S           28                                        B           C1

Result for indata 3 after filter #1:
10    S                 0           S           *           *                 *                 *           *
20    24          +-5   5           S           24          5                 -5          *           *
20    24          +-10  10          S           24          10                -10         *           *
30    AB                0           S           *           *                 *           B           *
30    AA          B-AA  5           S           *           *                 *           B
40    C1                0           S           *           *                 *           *           C1
40    C1                1           S           *           *                 *           B           *
40    C1                2           S           24          10                -10         *           *

Result for indata 3 after filter #2:
10    S                 0           S           *           *                 *                 *           *
20    24          +-5   5           S           24          5                 -5          *           *
30    AB                0           S           *           *                 *           B           *
30    AA          B-AA  5           S           *           *                 *           B
40    C1                0           S           *           *                 *           *           C1

Print for indata 3:
Mismatch 5:       S 24 AB C1  Warning: +-5
Mismatch 10:      S 24 AA C1  Warning: +-5 B-AA

4 个答案:

答案 0 :(得分:2)

首先,问题太长了。

其次,规则(#1,#1b,#2,#3和#4)令人困惑,需要澄清。

然而,尽管如此,这是我的建议。

如果在SQL中如何做不明显,请不要。

对于类似的东西,使用匹配的“规则”(“星号匹配任何东西”,“当存在重复项时选择具有最低不匹配的行”等),你有两个选择。

  1. 简化处理步骤,以便可以在SQL中实现它们。这通常是件好事。您当前的陈述很困惑,很难理解。简化时间花费的时间很长。

  2. 使用普通的编程语言。当你到达SQL中很难做到的事情时,不要“强迫”它们。从SQL获取数据并在PHP中处理它。

  3. SQL - 通常 - 很慢。当您拥有大量不适合内存并且正在进行事务更新的数据时,最好使用它。 1000行和30个字段是容易适合内存的大量数据。如果给你一批数据进行分析(没有更新)SQL没有多大帮助。

    在一个非常繁忙的网站中 - 使用PHP - 您可能会遇到很多并发用户的问题。在这种情况下,从PHP中获取它,因此它不在Apache下运行。在Apache耗尽内存之前,只需在PHP中完成。

答案 1 :(得分:1)

我不知道第3步是什么意思,但所有其他步骤都可以在SQL中完成,而且,它们可能应该在SQL中完成,效率更高。

我从您的标签中假设您正在使用MySQL数据库(了解它会有所帮助)。

我最初的注意事项将是以下几行:

 SELECT outdata.Pos,
     outdata.OutData,
     outdata.Warn,
     MIN(outdata.Mismatch),    
     outdata.Producer,
     outdata.Depl,
     outdata.DeplOffMax,        
     outdata.DeplOffMin,
     outdata.Axis
     outdata.Connection
 FROM outdata, indata
 WHERE
   (//some nasty type juggling here
     outdata.depl='*'
     OR outdata.deploffmin='*'
     OR indata.depl='*'
     OR (
        outdata.depl<>'*'
        AND outdata.deploffmin<>'*'
        AND indata.depl<>'*'
        AND outdata.depl-outdata.deploffmin>indata.depl
     )
   )  
 AND ( outdata.outdata=indata.outdata
   OR outdata.outdata='*'
   OR indata.outdata='*' )
 AND ( outdata.connection=indata.connection
   OR outdata.connection = '*'
   OR indata.connection='*' )
 AND (outdata.axis=indata.axis
   OR outdata.axis='*' 
   OR indata.axis='*' )
 ....repeat for all the fields you want to match       
 GROUP BY outdata.Pos,
     outdata.OutData,
     outdata.Warn,    
     outdata.Producer,
     outdata.Depl,
     outdata.DeplOffMax,        
     outdata.DeplOffMin,
     outdata.Axis
     outdata.Connection
 ORDER BY 4 ASC;

Simples。

下进行。

答案 2 :(得分:1)

我并不完全理解业务逻辑,但对于如此少量的数据,我不会费心去尝试在SQL中实现。将所有数据拉过来并使用PHP来应用过滤器可能会更快。

答案 3 :(得分:0)

我学到了一件事。任何可以计算的东西都不应该保存在数据库中