2

というテーブルtblCarがありID、 、CarNumberおよびその他の 32 のフィールドがあります。s1,s2,s3,.......,s32空席(A)、予約(B)、販売(S)のSEATSであるかどうかをコメントする専用の列として、 32列が記入されています。

そのデータベースから空席、予約席、売り切れ席を数えたいと思います。クエリはどのように記述すればよいですか?

Sデータベース内の stringと32 の異なる列からカウントする方法はありBますか?A

私が示したいのはそのようなものです..... S = 20、B = 10、A = 2;

SqlCommand cmd = new SqlCommand(
  "Select count(*) 
   FROM tblCar 
   WHERE s1= 'S' or s2= 'S' or s3= 'S' 
   or s4= 'S' or s5= 'S' or s6= 'S' 
   or s7= 'S' or s8= 'S' or s9= 'S' 
   or s10= 'S' or s11= 'S' or s12= 'S' 
   or s13= 'S' or s14= 'S' or s15= 'S' 
   or s16= 'S' or s17= 'S' or s18= 'S' 
   or s19= 'S' or s20= 'S' or s21= 'S' 
   or s22= 'S' or s23= 'S' or s24= 'S' 
   or s25= 'S' or s26= 'S' or s27= 'S' 
   or s28= 'S' or s29= 'S' or s30= 'S' 
   or s31= 'S' or s32= 'S' ", con
); 
count += cmd.ExecuteNonQuery(); 

これは私が「Sold」フィールドでどのように作業するかです。しかし、count = -128.i のみを示しました。

4

5 に答える 5

3

次の SQL クエリを試してください。

SELECT SUM(CASE WHEN State = 'S' THEN 1 ELSE 0 END) AS Sold
, SUM(CASE WHEN State = 'B' THEN 1 ELSE 0 END) AS Booked
, SUM(CASE WHEN State = 'A' THEN 1 ELSE 0 END) AS Available
FROM 
    (SELECT S1, S2, S3, S4, S5, S6
    FROM Seats) s
UNPIVOT
    (State FOR Seat IN (S1, S2, S3, S4, S5, S6)) AS rows;

ここでSQL Fiddle

例では6列のみを使用しましたが、あなたの場合は32列すべてに設定する必要がありますが、1回だけです

C# コード:

using SqlConnection conn = new SqlConnection(yourConnectionString)
{
    StringBuilder query = new StringBuilder();
    query.AppendLine("SELECT SUM(CASE WHEN State = 'S' THEN 1 ELSE 0 END) AS Sold");
    query.AppendLine(", SUM(CASE WHEN State = 'B' THEN 1 ELSE 0 END) AS Booked");
    query.AppendLine(", SUM(CASE WHEN State = 'A' THEN 1 ELSE 0 END) AS Available");
    query.AppendLine("FROM ");
    query.AppendLine("(SELECT S1, S2, S3, S4, S5, S6, S7, S8");
    query.AppendLine("(,S9, S10, S11, S12, S13, S14, S15, S16");
    query.AppendLine("(,S17, S18, S19, S20, S21, S22, S23, S24");
    query.AppendLine("(,S25, S26, S27, S28, S29, S30, S31, S32");
    query.AppendLine("FROM Seats) s");
    query.AppendLine("UNPIVOT");
    query.AppendLine("(State FOR Seat IN (S1, S2, S3, S4, S5, S6, S7, S8");
    query.AppendLine("(,S9, S10, S11, S12, S13, S14, S15, S16");
    query.AppendLine("(,S17, S18, S19, S20, S21, S22, S23, S24");
    query.AppendLine("(,S25, S26, S27, S28, S29, S30, S31, S32)) AS rows;");

    conn.Open();
    using SqlCommand command = new SqlCommand(query.ToString(), conn)
    {
        DataTable data = new DataTable();
        data.Load(command.ExecuteReader());
        //then get your values
        Int32 avialable = 0;
        Int32 booked= 0;
        Int32 sold = 0;
        if(data.Rows.Count > 0)
        {
            available = (Int32)data(0)("Available");
            booked = (Int32)data(0)("Booked");
            sold = (Int32)data(0)("Sold");
        }           
    }
}
于 2013-08-30T17:07:12.090 に答える
0

あなたはかなり厄介なテーブル構造を持っています。私はそれを変更することを検討しますが、あなたが持っているものでこれを行うことができます:

    SELECT SUM(CASE s1 WHEN 'S' THEN 1 ELSE 0 END) as sold,
     SUM(CASE s1 WHEN 'A' THEN 1 ELSE 0 END) as available,
     SUM(CASE s1 WHEN 'B' THEN 1 ELSE 0 END) as booked,
   FROM tblCar 
   UNION
    SELECT SUM(CASE s2 WHEN 'S' THEN 1 ELSE 0 END),
     SUM(CASE s2 WHEN 'A' THEN 1 ELSE 0 END),
     SUM(CASE s2 WHEN 'B' THEN 1 ELSE 0 END),
   UNION
    ... Repeat the above for each field.... yuck!...
   UNION
   SELECT SUM(CASE s32 WHEN 'S' THEN 1 ELSE 0 END),
     SUM(CASE s32 WHEN 'A' THEN 1 ELSE 0 END),
     SUM(CASE s32 WHEN 'B' THEN 1 ELSE 0 END)
于 2013-08-30T15:44:18.857 に答える
0

値を返す場合は、ExecuteScalar を使用する必要があります。

SqlCommand cmd = new SqlCommand("Select count(*) FROM tblCar WHERE s1= 'S' or s2= 'S' or s3= 'S' or s4= 'S' or s5= 'S' or s6= 'S' or s7= 'S' or s8= 'S' or s9= 'S' or s10= 'S' or s11= 'S' or s12= 'S' or s13= 'S' or s14= 'S' or s15= 'S' or s16= 'S' or s17= 'S' or s18= 'S' or s19= 'S' or s20= 'S' or s21= 'S' or s22= 'S' or s23= 'S' or s24= 'S' or s25= 'S' or s26= 'S' or s27= 'S' or s28= 'S' or s29= 'S' or s30= 'S' or s31= 'S' or s32= 'S' ", con); 
count += (int)cmd.ExecuteScalar();
于 2013-08-30T15:40:36.733 に答える
0

1 つの値を返すため、 を呼び出す必要があります.ExecuteScalar。Upi では、戻り値を int に変換する必要もあります。

count = Convert.ToInt32(sqlcmd01.ExecuteScalar());

MSDN から

クエリを実行し、クエリによって返された結果セットの最初の行の最初の列を返します。追加の列または行は無視されます。

探しているのは 1 つの値だけなので、単純に呼び出しcmd.ExecuteScalar(); ExecuteNonQuery()ExecuteReader()、他のものに適しています。(例ExecuteNoNQuery())INSERTS

この SO リンクは、違いを非常によくまとめています。

于 2013-08-30T15:42:38.840 に答える
-1

私の個人的な提案は、テーブルの再設計です。「利用可能」、「販売済み」、「予約」の 3 つの列のみを使用します。各列には int (bigint かな?) が保持されます。その int は、その条件を持つすべての座席のステータスをバイナリ コードとして保持します。たとえば、座席 1、2、3、および 4 のみが「販売済み」の座席である場合、その値は 1+2+4+8 = 17 になります。座席 4 および 5 のみが「販売済み」の場合、値は 8+16 = になります。 24. この方法では、販売済みの座席を見つけるためにすべての列を照会する必要はありません。「販売済み」列を照会するだけで、どの座席が販売されているかがわかります。

于 2013-08-30T18:23:17.597 に答える