我在查询后得到的内容如下:
   任务单号  物料名称    理论值     实际值
     1         水         20        22
     1         砂子       500        502
     1         水泥       300        302
     ..
     2         水         30        32
     2         砂子       500        502
     2         水泥       300        302
现客户需要如下格式:
   任务单号     水理论值   水实际值   砂子理论值   砂子实际值  水泥理论值   水泥实际值 ...
      1            20        22        500          502        300         302
      2            30        32          500        502         300        302好像是交叉表问题,请问如何转换?SQL语句如何写!使用环境:D6+access+ADO

解决方案 »

  1.   

    select a.no,a.lilun,a.shiji,b.lilun,b.shiji from (
    select * from table a where wuliaoname='shui'
    left join
    (
    select * from table b where wuliaoname='shazi' and a.no=b.no
    )
      

  2.   

    我的物料名称不固定,而且我通过两次交叉后再连接,还是无法得到上述结果(主要是显示表头的问题,是不是无解啊,要是固定表就好了,没有这么复杂)。另在Access中如何创建动态表。请各位高手再看看。
      

  3.   

    横竖没有一个固定的数,糟糕。
    采用数据集的方式,完成起来好像不可能。
    建议输出到Excel里面去作。这样就简单多了。
    哪位有时间的老兄认真试试?
    这个问题还是有点意义的。
      

  4.   

    Create table #TempTable
    (List_NO int,
     Water_T int,
     Water_A int,
     Sand_T int,
     Sand_A int,
     Cement_T int,
     Cement_A int)
    循环开始:
    Insert into #TempTable 
    values(
    ‘1’,
    (select 理论值 from 表名 where 任务单号='1' and 物料名称='水'),
    (select 实际值 from 表名 where 任务单号='1' and 物料名称='水'),
    (select 理论值 from 表名 where 任务单号='1' and 物料名称='沙子'),
    (select 实际值 from 表名 where 任务单号='1' and 物料名称='沙子'),
    (select 理论值 from 表名 where 任务单号='1' and 物料名称='水泥'),
    (select 实际值 from 表名 where 任务单号='1' and 物料名称='水泥'))
    循环结束
    select 
     List_NO as 任务单号,
     Water_T as 水理论值,
     Water_A as 水实际值,
     Sand_T as 沙子理论值,
     Sand_A as 沙子实际值,
     Cement_T 水泥理论值,
     Cement_A 水泥实际值 
    from #TempTable
      

  5.   

    function CreateTmptab(const AFieldDefs:TFieldDefs):TDataSet;
    var
    TempTable:TatClientDataSet;
    begin
    TempTable:=nil;
    Result:=nil;
    if AFieldDefs<>nil then
    begin
    try
    TempTable:=TatClientDataSet.Create(Application);
    TempTable.FieldDefs.Assign(AFieldDefs);
    TempTable.CreateDataSet;
    Result:=(TempTable as TDataSet);
    Except
    if TempTable<>nil then
    TempTable.Free;
    Result:=nil;
    raise;
    end
    end;
    end;
    {
    SouDataset源数据集
    ColField交叉表动态列字段
    RowField交叉表行字段
    DataField数据字段
    }
    function GenCrossTable(SouDataset:tdataset;ColField,RowField,DataField:string):tdataset;
    var
    Vdataset:tdataset;
    tmpdataset:tatclientdataset;
    DataSource:tdatasource;
    tmpstrs:tstrings;
    rowval,colval,dataval:string;
    i,j:integer;
    datatype:TFieldType;
    DataSize:integer;
    begin
    result:=nil;
    if (ColField=‘‘) or(RowField=‘‘)or(DataField=‘‘) then
    showmessage(‘All Field not be NULL!‘)
    else
    begin
    if (ColField=RowField)
    or(ColField=DataField)
    or(RowField=DataField) then
    showmessage(‘All Field not be Equ!‘)
    else
    if (self.SouDataSet.FieldByName(ColField).DataType=ftString)
    or (self.SouDataSet.FieldByName(ColField).DataType<>ftWideString)
    or (self.SouDataSet.FieldByName(ColField).DataType<>ftFixedChar)
    or (self.SouDataSet.FieldByName(ColField).DataType<>ftMemo) 
    or (self.SouDataSet.FieldByName(ColField).DataType<>ftFmtMemo) then
    begin
    try
    tmpstrs:=tstringlist.Create;
    Vdataset:=SouDataSet;
    Vdataset.First;
    for i:=0 to Vdataset.RecordCount-1 do
    begin
    if (varisnull(SouDataSet.FieldValues[colfield])=false) and (SouDataSet.FieldValues[colfield]<>‘‘) then
    if tmpstrs.IndexOf(SouDataSet.FieldValues[colfield])=-1 then
    begin
    tmpstrs.Add(SouDataSet.FieldValues[colfield]);
    end;
    Vdataset.Next;
    end;
    //生成动态列标题
    tmpdataset:=TClientDataSet.Create(Self);
    tmpdataset.FieldDefs.Add(rowfield,ftstring,50,False);
    for i:=0 to tmpstrs.Count-1 do
    begin
    with tmpdataset.FieldDefs do
    begin
    Add(tmpstrs.Strings[i],ftInteger,0,False);
    end;
    end;
    tmpdataset.FieldDefs.Add(‘Sum‘,ftInteger,0,False);
    DataSource:=tdatasource.Create(self);
    DataSource.DataSet:=tmpdataset;
    with DataSource do
    begin
    dataset:=Createtmptab(tmpdataset.FieldDefs);
    dataset.Open;
    end;
    //建立临时表
    Vdataset.First;
    for i:=0 to Vdataset.RecordCount-1 do
    begin
    rowval:=SouDataSet.fieldbyname(rowfield).AsString;
    colval:=SouDataSet.fieldbyname(colfield).AsString;
    dataval:=SouDataSet.fieldbyname(datafield).AsString;
    if dataval=‘‘ then dataval:=‘0‘;
    if DataSource.DataSet.Locate(rowfield,rowval,[loPartialKey]) then
    begin
    DataSource.DataSet.Edit;
    DataSource.DataSet.FieldByName(colval).AsString:=dataval;
    DataSource.DataSet.FieldByName(‘Sum‘).AsInteger:=
    DataSource.DataSet.FieldByName(‘Sum‘).AsInteger+strtoint(dataval);
    DataSource.DataSet.Post;
    end
    else
    begin
    DataSource.DataSet.Append;
    DataSource.DataSet.FieldByName(rowfield).AsString:=rowval;
    for j:=1 to DataSource.DataSet.Fields.Count-1 do
    DataSource.DataSet.Fields[j].AsCurrency:=0;
    DataSource.DataSet.FieldByName(colval).AsString:=dataval;
    DataSource.DataSet.FieldByName(‘Sum‘).AsString:=dataval;
    DataSource.DataSet.Post;
    end;
    Vdataset.Next;
    end;
    result:=DataSource.DataSet;
    //生成交叉表数据集
    tmpstrs.Free;
    except
    end;
    end
    else
    showmessage(‘ColField Must be of Type String!‘) ;
    end;
    end;
      

  6.   

    to qingfengman:
      在ACcess中可以用临时表吗?我还不会用。另外我的物料名称在我写程序时并不知道是什么,所以你提供的SQL语句没办法在程序中实现,而且我不知道有多少种物料会出现。
    to sxzz:
      每个任务的物料数固定,但每个任务的物料名称可能不一样,如在第一个任务当中,用户可能使用的水泥1,而在第二个任务当中,用户可能用水泥2,水泥3等。
    to hcjhjy:
      能把你实现的方法告诉我吗?有源代码更好,谢谢!这关系到饭碗问题;急!
    to zbderek:
      谢谢你提供的方法,我研究一下代码。SouDataset源数据集
    ColField交叉表动态列字段 在我提供的例子中是“物料名称“吗?
    RowField交叉表行字段 是”任务单号“吗?
    DataField数据字段 是”理论值“或”实际值“。另这能在Access中使用吗?我的开发环境为D6+Access+ADO.
     
      

  7.   

    首先,我有一个配置表,是给用户自己配置的(我在写程序时,并不知道客户会输入什么物料,但基本上是这些)。
    例如下:
       物料名称                 单元号    通道号     模式     显示位置    电流
        水                         A0       1         1          1
        外加剂1                    A8        1         2         2
        外加剂2                    A8        2         2         3
        粉煤灰                     B0        1         2         4
        水泥                       B0         2        2         5
        砂子                       C0         1        1          6
        石子1                      c0         1        1          7
        石子2                      D0         1        2          8
        石子3                      E0         1        2           9
        石子4                      E0        2         2          10
    即每一个客户一签合同之后,其物料是固定的,但每一个客户的配置都有可能不一样。配置一定,配方就跟着定了。但配方中有的物料是可选择的。例如:在A8和B0单元上就有选择存在。例如:水泥,用户在生产中可能选择水泥1,或者水泥2,水泥3等等。因为是由客户配置,所以我在建配方时给了一个选择号。如下:
    配方表头省略。配方子表:
       物料名称      选择号      标准用量
       水                        
        外加剂1                   
        外加剂2                   
        粉煤灰                   
        水泥           1,2,3..(只能选一种使用,在显示界面上应显示为水泥1,或者水泥2,水泥3,在数据库中也必须如实保存)            
        砂子                       
        石子1                      
        石子2                      
        石子3                      
        石子4 
    把配方传给下位机生产后。采集数据时,我用了主从表,来保存每一车的物料消耗信息。
    如下:
    任务单号  物料名称    理论值     实际值
         1         水         20        22
         1         砂子       500        502
         1         水泥1       300        302
         ..
         2         水         30        32
         2         砂子       500        502
         2         水泥2       300        302
    现客户需要的报表要象如下格式:
       任务单号     水理论值   水实际值   砂子理论值   砂子实际值  水泥1理论值   水泥1实际值 水泥2理论值 水泥2实际值...
          1            20        22        500          502        300             302           0           0
          2            30        32          500        502         0               0            300         302在每一车中,其中物料名称可能都一样,但有可能不一样。因此在做报表时,有可能同时会出现水泥1理论值
    、水泥1实际值、水泥2理论值、水泥3理论值等字段内容。至多有2种物料用户是可选择的,可选择的情况不会超过6种。
    因为,事先我并不知道用户会使用什么物料。因此感觉很难,不知道如何下手。
    我的老板说很容易,他没有做过WINDOWS程序。他是在DOS下用C语言开发的,而且每一个客户都有固定的的配置,客户不同,他就要修改源程序。请各位提供解决思路。
      

  8.   

    问题已按zbDerek的方法搞定,但还有一个小问题,就是在此生成的临时表怎样才能与别的表做连接和查询。