2015-06-30 38 views
5

我需要爲每星期等時刻表顯示單個用戶時間表,多重列值的where子句

場景:教師被分配給多個批次單週(如:BBA,數學和午前爲小時1和2)&(MBA,Maths,Forenoon for Hour 3 & 4)在同一日期說(30-06-2015)。我gridview的行將存儲爲1和2行作爲商店2等等。 .......

我的表定義:

CREATE TABLE [dbo].[test] (
    [datedif]  NVARCHAR (50) NOT NULL, 
    [hour]   INT    NULL, 
    [subject] NVARCHAR (MAX) NULL, 
    [faculty] NVARCHAR (MAX) NULL, 
    [attendence] BIT   NULL, 
    [dayweek]  NVARCHAR (50) NULL, 
    [weekmonth] NVARCHAR (MAX) NULL, 
    [batch]  NVARCHAR (MAX) NULL, 
    [section]  NVARCHAR (MAX) NULL, 
    [session]  NVARCHAR (MAX) NULL 
); 

表如下所示:

Datefdiff | hour | subject | faulty| batch 
----------+-------+----------+---------+-------+----------+--------+-------+----------+---------+------- 
30-06-2015| 1| Maths | Kevin | BBA 
30-06-2015| 2| Science | Amal | MBA 
30-06-2015|3 | chemistry|Jaya  |BBA 
30-06-2015|4 | chemistry|Jaya  |BBA 
30-06-2015|5 | chemistry|Jaya  |BBA 
31-06-2015 |1| science | Amal |BBA 
31-06-2015 |2| Maths | kevin |BBA 
31-06-2015 |3| Science | Amal |BBA 
31-06-2015 |4 | chemistry|Jaya  |BBA 
31-06-2015 |5| science | Amal |BBA 

預計產量爲僅系給出:阿邁勒

Datefdiff |hour|subject| batch |hour|subject | batch |faculty|hour | subject | batch | hour | subject | batch| hour | subject | batch | 
----------+-------+----------+-------+-------+----------+-------+-------+----------+ 
30-06-2015| 1 | Maths| BBA| 2| Science | MBA | 3| Science | BBA| 4| chemistry| BBA | 5 |Physics |MBA 
31-06-2015| 1 | Maths| BBA| 2| Science | MBA | 3| Science | BBA| 4| chemistry| BBA | 5 |Physics |MBA 

enter image description here

+6

這是一個糟糕的桌子設計。你不應該存儲數據來模仿某些顯示/表單。數據應該沒有轉移,這樣所有的「主題」數據以*相同*列結尾。然後添加一個額外的列,可以存儲數字1-5,併爲該列指定一個*名稱*,用於解釋數據表示的內容(您當前嵌入表格* metadata *的數據) –

+0

感謝您爲建議,但如果我可以通過在where子句中使用它來顯示教師計劃的詳細信息,那麼這將有所幫助,同時我會嘗試按照您的建議更改表格定義。 – Prhem

+1

在您更改表定義時,請記住日期值應該存儲在日期數據類型中,而nvarchar(max)適用於極長的unicode字符串。既然你的字符串看起來既簡短又簡單,你可以使用varchar(50)或其他任何適合你需要的長度。此外,我會建議您規範化您的數據 - 爲主題提供表格,批處理表格,錯誤表格等等。 –

回答

1

這可能是你的表的設計出發點:

declare @tbFaculty table (
     FacultyID int --identity(1,1) primary key 
    , Name varchar(50) 
) 

insert into @tbFaculty (FacultyID, Name) 
values (1, 'Kevin') 
     , (2, 'Amal') 

declare @tbBatch table(
     BatchID int --identity(1,1) primary key 
    , Name char(3) 
) 

insert into @tbBatch (BatchID, Name) 
values (1, 'BBA') 
     , (2, 'MBA') 

declare @tbClass table (
     [Hour] tinyint 
    , [Subject] nvarchar (128) 
    , [FacultyID] int 
    , [Attendence] bit 
    , [BatchID] char(3) 
    , [ClassDate] date 
) 

insert into @tbClass ([Hour], [Subject], FacultyID, Attendence, BatchID, ClassDate) 
values (1, 'Maths', 1, 1, 1, '2015-06-30') 
     , (2, 'Maths', 1, 1, 1, '2015-06-30') 
     , (3, 'Science', 2, 1, 1, '2015-06-30') 
     , (1, 'Science', 2, 1, 2, '2015-06-30') 
     , (2, 'Science', 2, 1, 2, '2015-06-30') 
     , (3, 'Maths', 1, 1, 2, '2015-06-30') 

select 
    cl.ClassDate 
    , cl.[Hour] 
    , cl.[Subject] 
    , ba.Name as BatchName 
    , fa.Name as FacultyName 
from 
    @tbClass cl 
    inner join @tbBatch ba on ba.BatchID = cl.BatchID 
    inner join @tbFaculty fa on fa.FacultyID = cl.FacultyID 
where 
    fa.Name = 'Amal' 

您也可以標準化主題。

0

下面是如何規範化數據,這將使查詢變得更簡單。

使用你的表定義,我插你的數據

INSERT INTO test(Datedif,hour1,subject1,faculty1,hour2,subject2,faculty2,hour3,subject3,faculty3,batch) 
VALUES ('30-06-2015',1,'Maths','Kevin',1,'Maths','Kevin',1,'Science','Amal','BBA'), 
     ('30-06-2015',1,'Science','Amal',1,'Science','Amal',1,'Maths','Kevin','MBA'); 

然後,我創建了一個新的規範化的結構與較窄的數據類型的數據。它有助於保持數據清潔以及不浪費存儲空間,這意味着查詢速度會更快,因爲它們無需處理太多數據。

CREATE TABLE new_test 
(
    dt   DATE   NULL, 
    hr   TINYINT   NULL, --holds values between 0 to 255 
    subj  VARCHAR(100) NULL, --plenty big enough. No need for NVARCHAR unless you are using Unicode characters 
    faculty  VARCHAR(100) NULL, 
    attendance BIT    NULL, 
    dayweek  TINYINT   NULL, 
    weekmonth TINYINT   NULL, 
    section  VARCHAR(100) NULL, --not sure what this is 
    sess  VARCHAR(100) NULL, --not sure what this is 
    batch  CHAR(3)   NULL --looks like there are three character codes 
); 

這是我正常化您的數據的地方。我不確定你是否有出席2,3,4等......如果你在你的實際表格中,那麼你應該修復我的代碼。

注:我從日期計算了每週和每週的月份。我做了我最好的猜測,如果他們不正確,然後隨意調整他們!

WITH norm_data 
AS 
(
SELECT datedif,hour1,subject1,faculty1,attendence1,dayweek,weekmonth,section,[session],batch FROM test 
UNION ALL 
SELECT datedif,hour2,subject2,faculty2,attendence1,dayweek,weekmonth,section,[session],batch FROM test 
UNION ALL 
SELECT datedif,hour3,subject3,faculty3,attendence1,dayweek,weekmonth,section,[session],batch FROM test 
UNION ALL 
SELECT datedif,hour4,subject4,faculty4,attendence1,dayweek,weekmonth,section,[session],batch FROM test 
UNION ALL 
SELECT datedif,hour5,subject5,faculty5,attendence1,dayweek,weekmonth,section,[session],batch FROM test 
) 

INSERT INTO new_test 
SELECT PARSE(datedif AS DATE USING 'de-DE') AS [datedif], 
     hour1, 
     subject1, 
     faculty1, 
     attendence1, 
     DATEPART(WEEKDAY,PARSE(datedif AS DATE USING 'de-DE')) AS dayweek, 
     datepart(day, datediff(day, 0, PARSE(datedif AS DATE USING 'de-DE'))/7 * 7)/7 + 1 AS weekmonth, 
     section, 
     [session], 
     batch 
FROM norm_data 

現在,讓我們看看你的新表

SELECT * 
FROM new_test 

如果它是正確的,那麼這裏是如何重命名錶

EXEC SP_rename @objname = 'test', --if you don't want to drop the old table 
       @newname = 'test_old' 

EXEC SP_rename @objname = 'new_test', --now give the new table the actual name 
       @newname = 'test' 


SELECT * 
FROM test 
+0

我已根據您的建議更改了我的表格。您可以在上面看到我更改的表格。如何加入它們並在網格視圖中顯示。請向我建議一些想法。請參閱上面的網格視圖,如明智我應該得到輸出 – Prhem

1

我只是要添加此ASA單獨答案。試試這個:

--INSERT INTO dbo.test(datedif,[hour],[subject],faculty,batch) 
--VALUES 
--('30-06-2015',1,'Maths','Kevin','BBA'), 
--('30-06-2015',2,'Science','Amal','MBA'), 
--('30-06-2015',3,'chemistry','Jaya','BBA'), 
--('30-06-2015',4,'chemistry','Jaya','BBA'), 
--('30-06-2015',5,'chemistry','Jaya','BBA'), 
--('31-06-2015',1,'science','Amal','BBA'), 
--('31-06-2015',2,'Maths','kevin','BBA'), 
--('31-06-2015',3,'Science','Amal','BBA'), 
--('31-06-2015',4,'chemistry','Jaya','BBA'), 
--('31-06-2015',5,'science','Amal','BBA'); 

WITH CTE_Hours 
AS 
(
    SELECT 
      1 AS hour1, 
      MAX(CASE WHEN [Hour] = 1 THEN [subject] END) AS subject1, 
      MAX(CASE WHEN [Hour] = 1 THEN [batch] END)  AS batch1 , 

      2 AS hour2, 
      MAX(CASE WHEN [Hour] = 2 THEN [subject] END) AS subject2, 
      MAX(CASE WHEN [Hour] = 2 THEN [batch] END)  AS batch2 

      --etc... 
    FROM dbo.test 
    WHERE faculty = 'Amal' 
) 

SELECT * 
FROM (
      SELECT DISTINCT datedif 
      FROM dbo.test 
     ) A 
CROSS JOIN CTE_Hours