2011-05-24 74 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

相關問題