一个带有多个查询的JSON

时间:2019-01-14 13:13:27

标签: php mysql json delphi delphi-2007

所以家伙们更新了我的问题:我有一个Delphi 2007函数“ ImportStudentMisses”:

procedure TWeb.ImportStudentMisses;
var
  SLMisses, SLClasses: TStringList;
  i: Integer;
  idClass, idStudent: integer;
begin
  SLMisses := TStringlist.Create;
  SLMisses.Duplicates := dupIgnore;
  SLMisses.Sorted := true;

  SLClasses := TStringlist.Create;
  SLClasses.Duplicates := dupIgnore;
  SLClasses.Sorted := true;

  try
    FTexto := '[INTERNET] - Fase 1';
    Synchronize(DoStatus);

    qryDestino.SQL.Clear;
    qryDestino.SQL.Add('SELECT ClassID, StudentID ');
    qryDestino.SQL.Add(' FROM ' + Config.InternetConfig.prefix + 'MissOneClass ');
    qryDestino.SQL.Add(' ORDER BY ClassID, StudentID');
    qryDestino.Open;
    while not qryDestino.eof do
    begin
      SLAulas.Add(formatfloat('00000000', qryDestino.Fields[0].AsInteger));
      SLFaltas.Add(formatfloat('00000000', qryDestino.Fields[0].AsInteger) + '-' + qryDestino.Fields[1].asString);
      qryDestino.Next;
    end;

    FTexto := '[INTERNET] - Fase 2';
    Synchronize(DoStatus);

    qryDestino.Close;
    qryDestino.SQL.Clear;
    qryDestino.SQL.Add('SELECT Date, DisciplineID, StudentID ');
    qryDestino.SQL.Add(' FROM ' + Config.InternetConfig.prefix + 'MissTwoClasses ');
    qryDestino.SQL.Add(' ORDER BY Date, DisciplineID, StudentID');
    qryDestino.Open;
    while not qryDestino.eof do
    begin //local Table
      qryOrigem.SQL.Clear;
      qryOrigem.SQL.Add('SELECT lNum FROM Class');
      qryOrigem.SQL.Add('WHERE lDiscipline = ' + IntTostr(qryDestino.Fields[1].AsInteger));
      qryOrigem.SQL.Add('  AND lDate = ' + IntTostr(trunc(qryDestino.Fields[0].AsDateTime)));
      qryOrigem.Open;
      qryOrigem.First;
      while not qryOrigem.eof do
      begin
        idClass := qryOrigem.Fields[0].AsInteger;
        if idClass > 0 then
        begin
          SLClasses.Add(FormatFloat('00000000', idClass));
          SLMisses.Add(formatfloat('00000000', idClass) + '-' + qryDestino.Fields[2].asString);
        end;
        qryOrigem.Next;
      end;
      qryOrigem.Close;

      qryDestino.Next;
    end;

    FTexto := '[INTERNET] - Fase 3';
    Synchronize(DoStatus);

    qryDestino.Close;
    qryDestino.SQL.Clear;
    qryDestino.SQL.Add('SELECT Date, StudentID ');
    qryDestino.SQL.Add(' FROM ' + Config.InternetConfig.prefix + 'MissTheDay ');
    qryDestino.SQL.Add(' ORDER BY Date, StudentID');
    qryDestino.Open;

    while not qryDestino.eof do
    begin //Local Table
      qryOrigem.SQL.Clear;
      qryOrigem.SQL.Add('SELECT lNum FROM Class');
      qryOrigem.SQL.Add('WHERE lDate = ' + IntTostr(trunc(qryDestino.Fields[0].AsDateTime)));
      qryOrigem.Open;
      qryOrigem.First;
      while not qryOrigem.eof do
      begin
        idClass := qryOrigem.Fields[0].AsInteger;
        if idClass > 0 then
        begin
          SLClasses.Add(FormatFloat('00000000', idClass));
          SLMisses.Add(formatfloat('00000000', idClass) + '-' + qryDestino.Fields[1].asString);
        end;
        qryOrigem.Next;
      end;
      qryOrigem.Close;
      qryDestino.Next;
    end;
    qryDestino.Close;
    qryDestino.SQL.Clear;

    qryOrigem.Close;


    qryOrigem.SQL.Clear;
    qryOrigem.SQL.Add('DELETE FROM Misses WHERE lClass = :pClass');
    for i := 0 to SLClasses.Count - 1 do
    begin
      idClass := StrToIntDef(SLClasses[i], 0);
      qryOrigem.Params[0].AsInteger := idClass;
      qryOrigem.ExecSQL;
    end;

    qryOrigem.SQL.Clear;
    qryOrigem.SQL.Add('INSERT INTO Misses');
    qryOrigem.SQL.Add(' (lClass, lStudent) VALUES ');
    qryOrigem.SQL.Add(' (:pClass, :pStudent)');

    for i := 0 to SLMisses.Count - 1 do
    begin
      idClass := StrToIntDef(Copy(SLMisses[i], 1, 8), 0);
      idStudent := StrToIntDef(Trim(Copy(SLMisses[i], 10, 8)), 0);

      if (idClass > 0) and (idStudent > 0) then
      begin
        try
          qryOrigem.Params[0].AsInteger := idClass;
          qryOrigem.Params[1].AsInteger := idStudent;
          qryOrigem.ExecSQL;
        except
          on e: Exception do
          begin
            FTexto := '[INTERNET] - Error ' + E.Message;
            Synchronize(DoStatus);
          end;
        end;
      end;
    end;
  except
    on E: Exception do
    begin
      FTexto := '[INTERNET] - ' + E.Message;
      Synchronize(DoStatus);
      reconect;
    end;
  end;
  SLMisses.Free;
end;

此功能将导入所有在一天中缺课的学生。而且我必须使该函数成为这样的JSON:

[{"ClassID":10,"StudentsID":[1,2]},{"ClassID":20,"StudentsID":[3,4]}]

如您所见,JSON具有(“ ClassID”:10)和缺少该类的学生列表(“ Students”:[1,2,3,4,5])。我已经尝试过下面的代码来制作想要的JSON。

$query = $database->query( "SELECT ClassID, GROUP_CONCAT(StudentID) AS StudentID FROM {$pfx}MissOneClass
GROUP BY ClassID ORDER BY ClassID");
$list = array();
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
    $list[] = array('ClassID' => $row['ClassID'], 
    'StudentID' => array_map('intval', explode(',', $row['StudentID'])));
    }
echo json_encode($list);

我又得到了这个JSON:

[{"ClassID":1,"StudentsID":[1,2,3,4]},{"ClassID":2,"StudentsID":[3,4,23]}]

JSON是我需要的JSON。但是有人告诉我,不仅必须像我一样使用所有表,而且还必须使用“ MissOneClass”。

此JSON将由将在数据库上插入JSON数据的JAVA应用程序使用。这就是角色问题。

谢谢!

1 个答案:

答案 0 :(得分:0)

在“联合”中,所使用的所有3个表中的列数应相同。检查union和union all之间的区别。在数据库上运行查询以检查结果。

SELECT ClassID, StudentID, null as Date, null as DisciplineID
FROM MissOneClass
union all
SELECT null as ClassID,StudentID, Date, DisciplineID
FROM MissTwoClasses
union all
SELECT null as ClassID, StudentID, Date, null as DisciplineID
FROM MissTheDay
ORDER BY Date, DisciplineID, ClassID, StudentID

您还可以使用join,它仍然以您想要合并JSON的方式令人困惑,这2种方式会产生不同的结果。在这种情况下,我假设学生证是外键。

SELECT ClassID, StudentID, Date, DisciplineID
FROM MissOneClass mo full outer join MissTwoClasses mt on mt.StudentID = mo.StudentID full outer join MissTheDay md md.StudentID = mo.StudentID