2

I have got a table called tblCar and there are ID, CarNumber and other 32 fields. 32 columns are filled as s1,s2,s3,.......,s32 since they are dedicated to remark whether it is for SEATS which are available(A), booking(B), and Sold(S).

I want to count available seats, booking seats and sold out seats from that database. how should i write a query?

Is there anyway to count from string S, B and A from 32 different columns in database?

What i want to show is like that..... 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(); 

this is how I work for "Sold" field.but it showed only count = -128.i did initialized count as 0

very9527
  • 891
  • 7
  • 9
  • 1
    Do you have any samples of what you are working with or have tried? – sealz Aug 30 '13 at 15:25
  • tried `s1+s2+s3.... AS s`? – bansi Aug 30 '13 at 15:27
  • 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(); this is how I work for "Sold" field.but it showed only count = -128.i did initialized count as 0 – Kuroi Shinigami Aug 30 '13 at 15:34
  • 2
    @Kuroi Shinigami You can edit your question to include the code so it fomrats nicely :) – sealz Aug 30 '13 at 15:36
  • Try cmd.ExecuteScalar() – sealz Aug 30 '13 at 15:39
  • If you would fix the table design to third normal form this would be easy. Repeating columns for seats is a violation of 3NF. – paparazzo Aug 30 '13 at 17:14

5 Answers5

3

Try this sql query:

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;

Here SQL Fiddle.

In example I used only 6 columns, but in your case you need set for all 32 columns, but only one time

C# code:

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");
        }           
    }
}
Fabio
  • 31,528
  • 4
  • 33
  • 72
0

You should use ExecuteScalar if you want it to return a value.

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();
randcd
  • 2,263
  • 1
  • 19
  • 21
0

Since you are returning 1 value you should call .ExecuteScalar. Upi will also need to Convert the return to an int.

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

From MSDN

Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored.

You are only looking for 1 value so simply call cmd.ExecuteScalar(); ExecuteNonQuery() and ExecuteReader() are better for other things. (Ex. ExecuteNoNQuery() for INSERTS)

This SO Link sums up the differences very well.

Community
  • 1
  • 1
sealz
  • 5,348
  • 5
  • 40
  • 70
0

You have a pretty nasty table structure and I would look at changing that, but with what you've got you can do this:

    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)
Kell
  • 3,252
  • 20
  • 19
-1

My personal suggestion is a redesign of the tables. Use only 3 columns, 'available', 'sold' and 'Booking'. Each column holds and int (bigint maybe?), that int will hold the status of all the seats that have that condition as a binary code. For instance, if seats 1,2,3 & 4 are the only 'sold' seats that value becomes 1+2+4+8 = 17. if only seats 4 & 5 are 'sold' the value would be 8+16 = 24. This way you don't have to query all the columns to find seats sold, you only have to query the 'sold' column and it will tell you which seats are sold .

orgtigger
  • 3,914
  • 1
  • 20
  • 22
  • What if later quantity of seats will increased to 78 pcs...? – Fabio Aug 30 '13 at 18:27
  • split each category into two or more columns (Since a bigint will no longer contain the binary value). By that point you should want to differentiate seating ('Balcony', 'Front row' or even by rows). Which is still a better solution than having 78 columns. – orgtigger Aug 30 '13 at 18:52
  • For me better solution will be redesign database as `Table('Cars'(ID, Number))`, `Table('Seats'(ID,Name))` and `Table('CarSeats'(CarID,SeatID,State)` where `State` will keep info about seat avialability. With this approach you don't need to change database if car seat's quantity increased. Only make changes through User interface... – Fabio Aug 30 '13 at 19:21
  • And just how to get 2 from 24 in a query? Nothing about that design would prevent 3 from being using in more than one column. – paparazzo Aug 30 '13 at 21:15
  • Bitwise operator '&' will tell you if the '2' bit is on in 24. 2 & 24 = true; 2 & 22 = false. And you would have to either A) flip the bit off in one before you flipped it on elsewhere B) use triggers – orgtigger Aug 30 '13 at 21:23
  • In TSQL how would I get a sum of 2 from 24 or a sum of 4 from 17? And how would 3 be prevented from being used in more than 1 column? – paparazzo Aug 30 '13 at 21:25
  • TSQL uses the bitwise operator, I have worked a LOT with flag values in the past. Where @value & 4 = 4 – orgtigger Aug 30 '13 at 21:27
  • to change database design is too late now. is there any possible way to count booking, sold and available fields according to s1,s2,s3,.............,s32??? – Kuroi Shinigami Aug 31 '13 at 01:03