I am writing a query to access health information from my student information system for state and county record compliance. We are using SQL Server 2000 (legacy system) as the backend. The query is this:
select
i.Description Immunization,
Case
When si.Exempt = 'P' Then Count (LName)
Else 0
END AS 'Personal Exempt',
Case
When si.Exempt = 'M' Then Count (LName)
Else '0'
END AS 'Medical Exempt',
Case
When si.Exempt = 'R' Then Count (LName)
Else 0
END AS 'Religious Exempt',
Case
When si.Exempt = 'I' Then Count (LName)--AS 'Personal Exemption'
Else '0'
END AS 'Had Illness'
from student cross join immunization i left join StImmunization si on si.sno = Student.sno and si.immcode = i.code
where Student.Status = 'A' and i.TotalReq > 0
Group BY i.Description, si.exempt
The output is this:
Immunization PersonalExempt MedicalExempt RelgiousExempt HadIllness
Chicken pox (Varicella) 0 0 0 6
Chicken pox (Varicella) 1 0 0 0
Hepatitis B 1 0 0 0
T_DAP 0 0 0 0
Polio 0 0 0 0
Diptheria, Tetanus,
Pertussis 0 0 0 0
Hepatitis B 0 0 0 0
Diptheria, Tetanus,
Pertussis 0 0 0 0
MMR 0 0 0 0
T_DAP 1 0 0 0
MMR 1 0 0 0
Polio 1 0 0 0
Chicken pox (Varicella) 1 0 0 0
I would like the output to combine the like rows of the columns so it looks like this and if necessary add like row and columns:
Imunization PersonalExempt Medical Exempt Religious Exempt Had Illness
Chicken pox (Varicella) 2 0 0 6
Hepatitis B 1 0 0 0
T_DAP 1 0 0 0
Polio 1 0 0 0
Diptheria, Tetanus,
Pertussis 1 0 0 0
Notice row one (below) is the sum of rows 2 and 13 (above). Any ideas on how to accomplish this?
Better to use SUM here -- then you can select a 1 or 0 to make the sum give the count.
Old SQL GROUP BY trick.
select
i.Description AS Immunization,
SUM(Case When si.Exempt = 'P' Then 1 Else 0 END) AS 'Personal Exempt',
SUM(Case When si.Exempt = 'M' Then 1 Else 0 END) AS 'Medical Exempt',
SUM(Case When si.Exempt = 'R' Then 1 Else 0 END) AS 'Religious Exempt',
SUM(Case When si.Exempt = 'I' Then 1 Else 0 END) AS 'Had Illness'
from student cross join immunization i left join StImmunization si on si.sno = Student.sno and si.immcode = i.code
where Student.Status = 'A' and i.TotalReq > 0
Group BY i.Description
I have a table as below
Name Grade SubjectAorB
Pooja B 1
Preeti C 0
Preeti C 1
Chintu A 1
Deepika B 0
Deepika B 1
Peter A 0
John A 0
Last column SubjectAorB has values as 0 and 1. 0 means Subject A and 1 means Subject B. A student can have either of the subject or both. I want output as below:
Name Grade Subject A Subject B
Pooja B 0 1
Preeti C 1 1
Chintu A 0 1
Deepika B 1 1
Peter A 1 0
John A 1 0
You can do this using conditional aggregation:
SELECT
Name,
Grade,
SubjectA = MAX(CASE WHEN SubjectAorB = 0 THEN 1 ELSE 0 END),
SubjectB = MAX(CASE WHEN SubjectAorB = 1 THEN 1 ELSE 0 END)
FROM #tbl
GROUP BY Name, Grade
I have a Table in DB named 'Retail'
CustomerID Itemset
1 1
1 3
1 7
2 6
2 7
3 4
... ...
I want to write this table in Datatable 'Matrix' where the Rows are Itemset={1,2,3,4,5,6....,k} and Columns are CustomerID={1,2,3,4,...,x}
and the rows are 1 if the 'Itemset' belongs to the CustomerID.
The output I want is like..
1 2 3 4 5 6 7 ............. x
1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0
2 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
3 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
4
5
6 /And so on!
7
8
9
`
I tried to code it but the problem is in VS Parameters for SQL Query don't work with Loops.
This is my code-
objConnection.Open()
Dim matrix As DataTable = New DataTable("Retail")
intcount = 0
For intcount = 1 To noofCustomerID_col
matrix.Columns.Add(intcount, GetType(Integer))
Next
Dim i As Integer
Dim workRow As DataRow
Dim Boolin As Boolean
For i = 1 To 9
ObjCommand.CommandText = "Select count(*) from Retail Where CustomerID=#in and Itemset=#in"
ObjCommand.Parameters.AddWithValue("#in", i) {{I Get Error here as I can't Loop Parameters}}
Boolin = ObjCommand.ExecuteScalar()
workRow = matrix.NewRow()
workRow(0) = i
workRow(1) = Boolin
matrix.Rows.Add(workRow)
Next
Kindly Help. I know this code can completely be wrong and it's okay if you can suggest totally different way of doing it. I've been stuck for quite some time now! Thanks.
If any clarification is needed I shall explain as many times needed in the comments.
Like Tab Alleman suggested, SQL PIVOT can come handy here.
Dynamic SQL is also needed.
DECLARE #DynamicColumn NVARCHAR(MAX),
#DynamicQuery NVARCHAR(MAX)
SELECT #DynamicColumn = SELECT '[' + CONVERT(NVARCHAR, CustomerID) + '],'
FROM Retail AS Customer
ORDER BY CustomerID
FOR XML PATH('')
SELECT #DynamicColumn = SUBSTRING(#DynamicColumn, 0, DATALENGTH(#DynamicColumn) / 2)--REMOVE EXTRA ","
SELECT #DynamicQuery = 'SELECT *
FROM ( SELECT CustomerID,
ItemSet
FROM Retail) AS D
PIVOT
(
COUNT([CustomerID])
FOR Itemset IN (' + #DynamicQuery + ')
) AS P'
EXECUTE(#DynamicQuery)
I just have a question about rebuild index.
After I had rebuilt the index, I found the physical order of pages is not completely "in order", I saw the pages which has small PID's is after the page has big PID's, as below, the page 7234 is after 23596, this is why. Why is the PID after building the index not in order from small to big or from big to small?
objectID PagePID PrePagePID NextPagePID
93243387 23590 0 0 10 NULL
93243387 7440 23583 0 2 1
93243387 7441 0 0 2 2
93243387 23583 0 7440 2 1
93243387 23589 0 23591 1 0
93243387 23591 23589 23592 1 0
93243387 23592 23591 23593 1 0
93243387 23593 23592 23594 1 0
93243387 23594 23593 23595 1 0
93243387 23595 23594 23596 1 0
93243387 23596 23595 7432 1 0
93243387 7432 23596 7433 1 0 <---------
93243387 7433 7432 7434 1 0
93243387 7434 7433 7435 1 0
93243387 7435 7434 7436 1 0
Try to run the following command just replace 'MyTable' with your tablename and verify if index is indeed fragmented.
SELECT DB_NAME(database_id) AS [Database Name]
,OBJECT_NAME(ps.OBJECT_ID) AS [Object Name]
,i.name AS [Index Name]
,ps.index_id
,ps.index_type_desc
,ps.avg_fragmentation_in_percent
,ps.fragment_count
,ps.page_count
,i.fill_factor
,i.has_filter
,i.filter_definition
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') AS ps
INNER JOIN sys.indexes AS i WITH ( NOLOCK )
ON ps.[object_id] = i.[object_id]
AND ps.index_id = i.index_id
WHERE database_id = DB_ID()
AND OBJECT_NAME(ps.OBJECT_ID) = 'MyTable'
ORDER BY avg_fragmentation_in_percent DESC
OPTION ( RECOMPILE );
after than reogranize all indexes on that table and after rebuild it.
Organize syntax
-- Reorganize all indexes on the HumanResources.Employee table.
ALTER INDEX ALL ON HumanResources.Employee
REORGANIZE ;
GO
Rebuild syntax:
ALTER INDEX PK_Employee_BusinessEntityID ON HumanResources.Employee
REBUILD;
GO
after all that rerun the first query.
I have the first 4 columns of data, and I wan't to use the Ranking functions in the SQL 2008 R2 to derive the fifth column. What's the best way to partition the data into subgroups based on the nextiteminsubgroup and previousiteminsubgroup fields?
Group OrderInGroup NextItemInSubGroup PreviousItemInSubGroup SubGroup
1 1 1 0 1
1 2 1 1 1
1 3 1 1 1
1 4 0 1 1
1 5 0 0 2
1 6 0 0 3
1 7 1 0 4
1 8 1 1 4
1 9 0 1 4
2 1 0 0 1
2 2 0 0 2
2 3 0 0 3
2 4 1 0 4
2 5 0 1 4
3 1 0 0 1
4 1 0 0 1
4 2 0 0 2
4 3 0 0 3
A recursive CTE solution:
DECLARE #t TABLE
([Group] INT
,OrderInGroup INT
,NextItemInSubGroup INT
,PreviousItemInSubGroup INT
,SubGroup INT
)
INSERT #t
VALUES
(1,1,1,0,1),(1,2,1,1,1),(1,3,1,1,1),(1,4,0,1,1),(1,5,0,0,2),(1,6,0,0,3),
(1,7,1,0,4),(1,8,1,1,4),(1,9,0,1,4),(2,1,0,0,1),(2,2,0,0,2),(2,3,0,0,3),
(2,4,1,0,4),(2,5,0,1,4),(3,1,0,0,1),(4,1,0,0,1),(4,2,0,0,2),(4,3,0,0,3)
;WITH recCTE
AS
(
SELECT [Group], OrderInGroup,NextItemInSubGroup , PreviousItemInSubGroup, 1 AS subgroup
FROM #t
WHERE OrderInGroup = 1
UNION ALL
SELECT r.[Group], t.OrderInGroup,t.NextItemInSubGroup , t.PreviousItemInSubGroup,
CASE WHEN r.NextItemInSubGroup = 1 THEN r.subgroup ELSE r.subgroup + 1 END
FROM recCTE AS r
JOIN #t AS t
ON t.[Group] = r.[Group]
AND t.OrderInGroup = r.OrderInGroup + 1
)
SELECT * FROM recCTE
ORDER BY [Group],OrderInGroup ;
P.S. it's best practice to avoid using SQL keywords (e.g. GROUP) as table/column names
Seems like 0 and 0 restart the ranking.
Select
Rank() Over (
Partition By
[Group]
, Case When [NextItemInSubGroup] + [PreviousItemInSubGroup] = 0
Then 0
Else 1
End
Order By [OrderInGroup]
) as [SubGroup]
From Your_Table;