2011-05-24 161 views
2

SQL数据类型: 的SerialNumber/PARTNUMBER - 为nvarchar(50), 数量 - INT在数据表如何在C#中显示来自所需参数的记录?

加载记录:

SerialNumber | PartNumber | Quantity 
     1  |  0001 | 20 
     2  |  0001 | 10 
     3  |  0001 | 20 
     5  |  0001 | 20 

要求:

1.Get序列号,他们的产品数量的SUM = 40

2.获取最低串行优先(FIFO)

哪种样品结果应该是这样的:

SerialNumber | PartNumber | Quantity 
     1  |  0001 | 20 
     3  |  0001 | 20 

如何得到这个结果?

谢谢问候

+0

我是否正确地将您所需的查询汇总为'返回满足给定零件编号的数量要求的一组行'?当然,可能有0个或多个候选集。这看起来并不是很友好 - 这种逻辑很可能在不同的编程语言中得到更好的处理。 – 2011-05-24 22:46:05

+0

是指一个或多个记录的数量总和为40的位置? – 2011-05-24 22:49:31

+0

是的,它是一个艰难的.. – BizApps 2011-05-24 23:13:02

回答

3

好的,所以你删除了sql标签,并引入了FIFO作为要求。这澄清了事情。

你的答案的心脏是在这里:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 

namespace SO_Forms_Demo 
{ 
    class SumFifo 
    { 

     DataTable _dt; 

     public SumFifo(DataTable dt) 
     { 
      _dt = dt; 
     } 

     public DataView GetAll() 
     { 
      return new DataView(_dt, null, null, DataViewRowState.CurrentRows); 
     } 

     public DataTable GetFIFO(string partNumber, int qty) 
     { 
      DataTable resultsTable = _dt.Clone(); 

      //the generic collection type that represents a FIFO relationship is a Queue 
      Queue<DataRow> PartRows = new Queue<DataRow>(_dt.Select("partNumber = '" + partNumber + "'", "serialNumber")); 

      //iterate through the queue adding rows and decreasing quantity till your requirment is met. 
      foreach (DataRow row in PartRows) 
      { 
       if (qty > 0) 
       { 
        resultsTable.ImportRow(row); 
        qty -= int.Parse(row["qty"].ToString()); 
       } 
      } 

      return resultsTable; 
     } 
    } 
} 

的“GetFIFO”的方法将遍历所提供的数据集,首先要创建一个队列(即有正确的部分号码数据行的FIFO收集它会遍历。该集合将对象数量减少选定的数量直到达到0。

为了测试这个构建看起来格式如:

enter image description here

,看起来像一个代码:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace SO_Forms_Demo 
{ 
    public partial class FormFIFO : Form 
    { 
     DataTable _table; 
     public FormFIFO() 
     { 
      InitializeComponent(); 

      _table = new DataTable("fifo"); 
      _table.Columns.Add(new DataColumn("serialNumber")); 
      _table.Columns.Add(new DataColumn("partNumber")); 
      _table.Columns.Add(new DataColumn("qty")); 
      _table.AcceptChanges(); 
      _table.Rows.Add(new object[3] { 1, "0001", 20 }); 
      _table.Rows.Add(new object[3] { 2, "0002", 10 }); 
      _table.Rows.Add(new object[3] { 3, "0001", 20 }); 
      _table.Rows.Add(new object[3] { 4, "0002", 10 }); 
      _table.Rows.Add(new object[3] { 5, "0001", 20 }); 
      _table.Rows.Add(new object[3] { 6, "0002", 10 }); 
      _table.AcceptChanges(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      dataGridView1.DataSource = null; 
      SumFifo sumFifo = new SumFifo(_table); 
      dataGridView1.DataSource = sumFifo.GetAll(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      dataGridView1.DataSource = null; 
      SumFifo sumFifo = new SumFifo(_table); 
      dataGridView1.DataSource = sumFifo.GetFIFO(textBox1.Text,int.Parse(textBox2.Text)); 
     } 
    } 
} 

现在很明显,你有很长的路要走,使这个“有用/健壮/等。“但GetFIFO方法是您的问题的基本答案在C#

+0

很棒.... @ Cos Callis ...非常感谢! – BizApps 2011-05-25 03:46:14

0

我建议写返回所有行对于给定的零件编号和执行计算,以确定在不同的编程语言要使用的序列号的SQL查询。 SQL非常适合基于集合的操作,但是这个问题需要找到SQL不会擅长的子集的特定约束子集。

当您获得零件的行集合。我建议采用深度或宽度优先搜索。如果您没有要求在“最小数量的连续编号”中完成数量,并且在每个阶段选择“小于缺陷的最大数量”,则深度优先可能是最好的方法,这应该是一个合理的策略推进搜索。

+0

是啊,它真的很难...如果它的顶部(1)在SQL中应该很容易..但这是什么要求... – BizApps 2011-05-24 23:00:36

+0

@John - 我错过了C#部分 - 我修改了我的回应相应。 – 2011-05-24 23:06:29

+0

..是啊如何处理这个在C#.Just编辑我的文章。 – BizApps 2011-05-24 23:58:36

2

这绝对可以在SQL中完成,但优化它以适用于大集合将是挑战。下面是一个解决方案,它使用公共表格表计算目标零件编号的可能排列组合,将这些排列组合到它们的数量总和中,并选择SUM与目标匹配的第一个排列组合。

该排列,然后用来识别SerialNumbers从数据集选择:

declare @partNum char(4) 
SET @partNum = '0001' 
declare @quantity int 
SET @quantity = 40 

declare @data TABLE (
    SerialNumber int identity(1,1), 
    PartNumber char(4), 
    Quantity int 
); 

INSERT INTO @data (PartNumber, Quantity) VALUES ('0001', 20); 
INSERT INTO @data (PartNumber, Quantity) VALUES ('0001', 10); 
INSERT INTO @data (PartNumber, Quantity) VALUES ('0001', 20); 
INSERT INTO @data (PartNumber, Quantity) VALUES ('0002', 20); 
INSERT INTO @data (PartNumber, Quantity) VALUES ('0001', 20); 

WITH 
cte_items as (
    select * from @data where PartNumber = @partNum 
), 
cte_perms as (
    select cast(cast(SerialNumber as binary(4)) as varbinary(max)) as perm, 1 as numentries 
    from cte_items 
    union all 
    select cast(n.SerialNumber as binary(4)) + p.perm, p.numentries + 1 
    from cte_perms p 
    join cte_items n on n.SerialNumber < cast(substring(perm,1,4) as int) 
), 
cte_permlist as (
    select row_number() over (order by (select 1)) as permnum, perm 
    from cte_perms 
) 

SELECT d1.SerialNumber, d1.PartNumber, d1.Quantity 
FROM @data d1 
INNER JOIN (
    SELECT 
     cast(substring(p.perm, 4*n.SerialNumber-3, 4) as int) as SerialNumber 
    from cte_permlist p 
    join @data n on n.SerialNumber = n.SerialNumber 
    where cast(substring(p.perm, 4*n.SerialNumber-3, 4) as int) != 0 
     and p.permnum = (
      SELECT TOP 1 permutations.permnum 
      FROM @data d2 
      CROSS APPLY (
       SELECT 
        p.permnum, 
        cast(substring(p.perm, 4*n.SerialNumber-3, 4) as int) as SerialNumber 
       from cte_permlist p 
       join @data n on n.SerialNumber = n.SerialNumber 
       where cast(substring(p.perm, 4*n.SerialNumber-3, 4) as int) != 0 
      ) permutations 
      WHERE PartNumber = @partNum 
       and permutations.SerialNumber = d2.SerialNumber 
      GROUP BY permutations.permnum 
      HAVING SUM(d2.Quantity) = @quantity 
      ORDER BY permnum desc 
     ) 
    ) pSn on pSn.SerialNumber = d1.SerialNumber 

结果:

SerialNumber PartNumber Quantity 
------------ ---------- ----------- 
1   0001  20 
3   0001  20 

一旦查询优化器获取与此做了它应该是相当有效率除非对于目标零件编号,有不止一个排列组合。

+0

它可能在C#中做到这一点? – BizApps 2011-05-25 03:04:43

相关问题