0

私は次のコードを持っています...

<?php
$sql = 
    "SELECT 
         tickets.company, tickets.datetime, tickets.ticketnumber, 
         customer_notes.customer, customer_notes.timestamp, customer_notes.notes 
    FROM 
       tickets, customer_notes 
    WHERE tickets.company = '".$_GET["seq"]."' AND 
          customer_notes.customer = '".$_GET["seq"]."' 
    GROUP BY customer_notes.customer, tickets.company ";

    $rs=mysql_query($sql,$conn) or die(mysql_error());
    echo '<table width="100%" border="0" cellspacing="5" cellpadding="5">';
    while($result=mysql_fetch_array($rs))
    {
        echo '<tr>
                <td>'.$result["timestamp"].'</td>
                <td>'.$result["notes"].'</td>
              </tr>
              <tr>
                <td>'.$result["datetime"].'</td>
                <td>'.$result["ticketnumber"].'</td>
              </tr>';
    }
    echo '</table>';
    ?>

チケット テーブルと customer_notes テーブルにはまったく参照がありません。これらは完全に分離されています。

チケット テーブルは、顧客が抱えている問題をログに記録するときのサポート チケット用です。次に、customer_notes テーブルは、顧客が電話をかけたとき用です。電話で話されたすべてがこのテーブルに記録されます。

チケットテーブルと顧客メモテーブルのデータを日時順に表示しようとしています。

したがって、チケットが作成され、メモが追加され、別のメモが追加された場合、チケットは上記のコードを使用して日時順に表示されますが、正しく表示されません

4

5 に答える 5

4

あなたの質問は少し漠然としているので、2 つの選択肢を提示します。

1) 2 つの類似したテーブルがあり、両方からすべてのレコードを選択したい場合: (両方のテーブルにある列 A、B、C からすべてのデータが必要な場合)

テーブルの構造が似ている(同じ列)場合は、unionを使用する必要があります。ユニオンは両方のテーブルから結果を取得し、それらを 1 つの結果セットに結合します。ただし、両方のテーブルの構造が同じである必要があります (または、少なくとも、構造全体が同一でない場合は、類似したフィールドを呼び出す必要があります)。

2)テーブルには異なる列があり、共通の属性でそれらをマージしたい場合: (最初のテーブルの列 A、b、C が必要な場合、次に 2 番目のテーブルの列 D、E、F が必要な場合)。

プライマリ/外部キーを使用して参加する必要があります。最も一般的な結合は、左または右のテーブルが一致しない場合にそのレコードを除外する内部結合です。それはすべて、あなたが何をしようとしているかに依存します(あなたの質問は少し曖昧でした)

また、コードは SQL インジェクション攻撃に対して非常に脆弱です。

于 2013-03-05T16:38:46.050 に答える
1

ここでやろうとしているのは、顧客のメモを含むチケットのリストを取得することだと思います。この場合、出力を行う前にリスト全体をループする必要があるかもしれませんが、単純な左結合が機能します。

顧客のメモがチケットに正確にどのように関連しているかはわかりませんが、クエリで会社を使用していることがわかります。

SELECT t.company, t.ticketnumber, t.datetime, t.ticketnumber, c.customer, c.timestamp, c.notes
FROM tickets t
LEFT JOIN customer_notes c ON (t.company = c.customer)
WHERE t.company = %s
ORDER BY t.company, t.datetime, t.ticketnumber, c.timestamp DESC

したがって、次のことができます。

mysql_query(sprintf($theQueryFromAbove, mysql_real_escape_string($_GET['seq'])));

これにより、フラットな結果セットが得られます。つまり、チケット データが複数回取得されますが、会社/チケット番号のすべてのデータが連続した行セットに含まれるため、出力の準備が容易になります。 .

于 2013-03-05T16:52:43.693 に答える
1

UNION を使用してこれを解決することができました

$sql ="
    SELECT datetime as datetime2, CONCAT(CONCAT('<strong>Ticket</strong> - ', ticketnumber, '<br>'),summary) as displaydata from tickets where company = '".$_GET["seq"]."'
    UNION
    SELECT timestamp as datetime2, CONCAT('<strong>Note</strong><br>',notes) as displaydata from customer_notes where customer='".$_GET["seq"]."'
    order by datetime2 DESC ";
    $rs=mysql_query($sql,$conn) or die(mysql_error());
    echo '<table width="100%" border="0" cellspacing="5" cellpadding="5">';
    while($result=mysql_fetch_array($rs))
    {
        echo '<tr>
            <td width="150px" valign="top">'.$result["datetime2"].'</td>
            <td valign="top">'.nl2br($result["displaydata"]).'</td>
          </tr>';
}
echo '</table>';
于 2013-03-07T23:31:55.123 に答える
0

最初に行う必要があるのは、SQL ステートメントの変更です。テーブル間のリンクはtickets.companyandのようですcustomer_notes.customer (この仮定は間違っていることが判明しました。以下の編集を参照してください)。SQL を変更して、両方のテーブルを JOIN でリンクできるようになりました。メモのないチケットが引き続きリストされるように、LEFT 結合を使用しました。

(読みやすくするために、次のコード サンプルは単なる SQL であるため、PHP の場合は引用符で囲む必要があります。)

SELECT tickets.company, tickets.datetime, tickets.ticketnumber, 
  customer_notes.timestamp, customer_notes.notes 
FROM tickets
LEFT JOIN customer_notes ON tickets.company=customer_notes.customer
ORDER BY tickets.datetime DESC, customer_notes.timestamp DESC

チケット作成日の降順です。すべてのメモは、タイムスタンプの降順に並べられます。この選択の結果は、次のようになります

company      datetime   ticketnumber timestamp        notes
ACME Corp    2013-01-12     2        20130113110034   firstnotetext
ACME Corp    2013-01-12     2        20130113140245   secondnotetext
Somecorp     2013-01-10     1

1 つの会社のチケットとメモのみを一覧表示する場合は、次のように ORDER BY 句の直前に WHERE 句を挿入する必要があります。

WHERE tickets.company = {put your escaped $_GET parameter here}

SQL ステートメントの $_GET['seq'] パラメーターにパラメーターを入れるときは、SQL インジェクションを防ぐために適切にエスケープしてください。

$sql="WHERE tickets.company = '".mysql_real_escape_string($_GET['seq'])."'";

編集:コメントで、2つのテーブルは互いに関連していないと述べました。通常は 2 つの SELECT を使用するだけですが、日付/時刻でソートされた 1 つのテーブルが必要です。したがって、UNION を使用する必要があります。

SELECT company as name, datetime as t, ticketnumber as more_info
UNION
SELECT customer as name, timestamp as t, notes as more_info
ORDER BY t DESC

PS実際に試したことはありませんが、私の記憶が正しければ、順序付けに関して日時フィールドとタイムスタンプを交換できます。そうでない場合は、使用して両方を同じ日付/時刻形式にキャストするだけですTIMESTAMP(datetime) as t

于 2013-03-05T16:54:04.347 に答える
0

以下の小さな変更は、うまくいくかもしれません。2 つのテーブル間の関係がなければ、テーブルのデカルト積を取得できると思います。

<?php
$sql = 
    "SELECT 
         tickets.company, tickets.datetime, tickets.ticketnumber, 
         customer_notes.timestamp, customer_notes.notes 
    FROM 
       tickets, customer_notes 
    WHERE tickets.company = customer_notes.customer AND 
          customer_notes.customer = '".$_GET["seq"]."' 
    GROUP BY tickets.company ";

    $rs=mysql_query($sql,$conn) or die(mysql_error());
    echo '<table width="100%" border="0" cellspacing="5" cellpadding="5">';
    while($result=mysql_fetch_array($rs))
    {
        echo '<tr>
                <td>'.$result["timestamp"].'</td>
                <td>'.$result["notes"].'</td>
              </tr>
              <tr>
                <td>'.$result["datetime"].'</td>
                <td>'.$result["ticketnumber"].'</td>
              </tr>';
    }
    echo '</table>';
    ?>
于 2013-03-05T16:52:30.720 に答える