2013-08-30 53 views
2

我有一個名爲tblCar的表,其中有ID,CarNumber等32個字段。 32列填寫爲s1,s2,s3,.......,s32,因爲它們專用於說明是否適用於可用(A),預訂(B)和已售出(S)的SEATS。來自數據庫中不同列的數據計數

我想計算可用座位,預訂座位並從該數據庫中售完座位。 我該如何寫一個查詢?

無論如何,從字符串SBA從數據庫中的32個不同列數?我想展示的就是那樣..... 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(); 

這是我的「已售出」的工作field.but它顯示只算= -128.i並初始化計數爲0

+1

您是否有任何樣品與您一起工作或嘗試過? – sealz

+0

嘗試過's1 + s2 + s3 .... AS s'? – bansi

+0

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 '或s7 ='S'或s8 ='S'或s9 ='S'或s10 ='S'或s11 ='S'或s12 ='S'或s13 ='S'或s14 ='S'或s15 ='S'或s16 ='S'或s17 ='S'或s18 ='S'或s19 ='S'或s20 ='S'或s21 ='S'或s22 ='S'或s23 = 'S'或s24 ='S'或s25 ='S'或s26 ='S'或s27 ='S'或s28 ='S'或s29 ='S'或s30 ='S'或s31 ='S '或s32 ='S'「,con); count + = cmd.ExecuteNonQuery(); 這是我爲「已售出」字段工作的方式,但它只顯示count = -128.i的初始化數爲0 –

回答

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(); 
+0

有錯誤! count是整數類型,返回的是一個對象。 –

+2

'count + =(int)cmd.ExecuteScalar();' – Damith

+0

@Kuroi Shinigami你需要轉換爲Int。請參閱我的回答 – sealz

0

由於您要返回1值,因此應撥打.ExecuteScalar。 Upi也需要將返回值轉換爲int。

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

從MSDN

執行查詢,並在查詢返回的結果集返回第一行的第一列。其他列或行將被忽略。

你只找1個值,只需調用cmd.ExecuteScalar();ExecuteNonQuery()ExecuteReader()是其他事情做得更好。 (對於INSERTS,例如ExecuteNoNQuery()

This SO Link總結了很好的差異。

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) 
+0

是不是那個查詢太長? –

+0

我不能得到一個簡單和短的查詢,可以生成計數預訂,出售和可用? @Kell –

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列集,但只有一次

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"); 
     }   
    } 
} 
-1

我個人的建議是的重新設計表。只使用3列,'可用','出售'和'預訂'。每列保存並且int(bigint也許?),int將把所有具有該條件的位置的狀態保存爲二進制代碼。例如,如果座位1,2,3是唯一的「售出」座位,其價值變成1 + 2 + 4 + 8 = 17。如果僅座位4「& 5」被售出,則價值將是8 + 16 = 24。通過這種方式,您不必查詢所有列以查找已售座位,只需查詢「已售出」列,即可查詢哪些座位已售出 。

+0

如果後來的座位數量會增加到78個...怎麼辦? – Fabio

+0

將每個類別分成兩列或更多列(由於bigint將不再包含二進制值)。到那時你應該想要區分座位('陽臺','前排'或者甚至是排列)。與78列相比,這仍然是更好的解決方案。 – orgtigger

+0

對我來說,更好的解決方案是將數據庫重新設計爲'Table('Cars'(ID,Number))'''Table('Seats'(ID,Name))'和'Table('CarSeats'(CarID,SeatID,State )'哪裏'國家'將保持有關座椅的可通過性的信息。使用這種方法,您不需要更改數據庫,如果汽車座椅的數量增加只通過用戶界面進行更改... – Fabio