Grouping in classic ASP - sql-server-2008

I have a list of graduates in a mssql table with several years of renewals. I have been tasked with listing them by grad id and their renewal years separated by commas instead of one on each line. Some users have as many as 8 renewals.
They are listed as such:
Lisa Jones 123456 2001 CMC
Lisa Jones 123456 2002 CMC
Lisa Jones 123456 2003 CMC
ultimately I would like to see:
Lisa Jones 123456 2001, 2002, 2003 CMC
Is there a way I can do this with a sql query or an asp function?? I have over 2300 records where the Grad ID is unique (123456) but the renewal dates are different. Grouped by grad id the count would be 275.

I would do this one in SQL, myself. Quite easy using the STUFF function in SQL Server 2008+.
I have mocked up an example using a table variable. You would swap the usage of the table variable for your real table named hubspot (replace #hubspot with hubspot).
Example setup (only needed to run the full example):
declare #hubspot table
(
name varchar(100),
grad_id int,
renewal_year varchar(10),
certification_type varchar(10)
)
insert into #hubspot values ('Lisa Jones', 123456, 2001, 'CMC')
insert into #hubspot values ('Lisa Jones', 123456, 2002, 'CMC')
insert into #hubspot values ('Lisa Jones', 123456, 2003, 'CMC')
insert into #hubspot values ('Lisa Jones', 123456, 2004, 'CMC')
Use this SQL on your table hubspot:
select name
, grad_id
, STUFF((select ', ' + renewal_year
from #hubspot b
where b.grad_id = a.grad_id
for xml path('')), 1, 2, '') as renewal_years
, certification_type
from #hubspot a
group by name
, grad_id
, certification_type
Output:
Documentation on STUFF function:
https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-2017

Related

SSRS - Lookup only on certain columns in a matrix

I have a matrix table with a column group "Application questions" let's say these are in table 1. Some of the questions have unique string values such as: Name, ID number, email address. But others have an integer value that relates to an actual value for a separate lookup table (table 2), for example, the values for the column "Gender" are 1, 2, 3, for Male, Female, Other. Is there a way in the lookup function that I can isolate the columns that only have integer values or alternatively ignore the other columns with unique string values?
Table1
NAME ATTRIBUTE_id ATTRIBUTE
-----------------------------------------
James 5 1
James 6 james#email.com
James 7 8
Table2
Lookup_id ATTRIBUTE_id Description
-----------------------------------------
1 5 Male
2 5 Female
3 5 Other
8 7 New York
9 7 Los Angeles
Output
NAME | Email | Gender | City
-------------------------------------------------------
James james#email.com Male New York
Hope that makes sense!
Thank you.
I think this will be easier to do in your dataset query.
Below I have recreated your sample data and added an extra person in to make sure it's working as expected.
DECLARE #t TABLE (Name varchar(10), AttributeID INT, AttributeMemberID varchar(50))
INSERT INTO #t VALUES
('Mary', 5, '2'),
('Mary', 6, 'Mary#email.com'),
('James', 5, '1'),
('James', 6, 'james#email.com'),
('James', 7, '8')
DECLARE #AttributeMembers TABLE (AttributeMemberID INT, AttributeID int, Description varchar(20))
INSERT INTO #AttributeMembers VALUES
(1, 5, 'Male'),
(2, 5, 'Female'),
(3, 5, 'Other'),
(8, 7, 'New York'),
(9, 7, 'Los Angeles')
I also added in a new table which describes what each attribute is. We will use the output from this as column headers in the final SSRS matrix.
DECLARE #Attributes TABLE(AttributeID int, Caption varchar(50))
INSERT INTO #Attributes VALUES
(5, 'Gender'),
(6, 'Email'),
(7, 'City')
Finally we join all three togther and get a fairly normalised view for the data. The join is a bit messy as your current tables use the same column for both integer based lookups/joins and absolute string values. Hence the CASE in the JOIN
SELECT
t.Name,
a.Caption,
ISNULL(am.[Description], t.AttributeMemberID) as Label
FROM #t t
JOIN #Attributes a on t.AttributeID = a.AttributeID
LEFT JOIN #AttributeMembers am
on t.AttributeID = am.AttributeID
and
CAST(CASE WHEN ISNUMERIC(t.AttributeMemberID) = 0 THEN 0 ELSE t.AttributeMemberID END as int)
= am.AttributeMemberID
ORDER BY Name, Caption, Label
This gives us the following output...
As you can see, this will be easy to put into a Matrix control in SSRS.
Row group by Name, Column Group by Captionand data cell would beLabel`.
If you wanted to ensure the order of the columns, you could extend the Attributes table to include a SortOrder column, include this in the query output and use this in SSRS to order the columns by.
Hope that's clear enough.

Create a table/tables with with parent/child hierarchy in SQL

Im currently a self-taught programmer, and i know and have worked with noSQL databases.
Right now i want to learn better the relational databases. I'm doing a project for myself and trying to deep my knowledge in here, and i'm kinda confused. My goal is to create a simple database with child/parent hierarchy. I want to create a database for person, in which i will only have access to the identification number(no name, age, or whatever). And this person can have childs or parents or both. How do advice me to structure this. I want to query the table so i can retrieve all the childs and parents of a certain individual. My first thought was to build a table with only the PK(Id_Number) and other table with composite key(FK->Id_Number and Id_parent), but i dont think it would work like this? How should i do it? Do you have any thoughts on this? thank you!
To help visualization (instead of identification number, lets use name), i have this object, how should i store it?
{
human: "Joe",
child: [
{
human: "Kevin",
child: [
{
human: "Joaquin",
},
{
human: "leticia",
},
],
},
{
human: "Mary",
child: [
{
human: "Joaquin",
child: [{ human: "levi" }],
},
{
human: "leticia",
},
],
},
],
};
The goal is to know all families hierarchies like who is the son, parent and possibly brothers of the kevin for example.
The simplest way of modeling a parent relationship between entities is by using one table for the entity (node in the graph), and another for the relationship (arc between nodes in the graph).
For example:
create table person (
id int primary key not null,
identification_number varchar(50) not null
);
create table parent_child_relationship (
parent_id int not null references person (id),
child_id int not null references person (id),
primary key (parent_id, child_id),
);
You can also use a single table, but separating the relationship from the entity gives you the flexibility to account for people having multiple parents (natural, legal, adopted, etc.) and also to account for life changes.
This is how I created a consolidated hierarchy in AWS redshift.
this will create top to bottom hierarchy for every node in the hierarchy tree
Sample data Schema:
create table kpi_dashboard.employee (
id int,
name varchar (20),
manager_id int
);
Insert data
insert into schema_name.employee(id, name, manager_id) values
(100, 'Carlos', null),
(101, 'John', 100),
(102, 'Jorge', 101),
(103, 'Kwaku', 101),
(110, 'Liu', 101),
(106, 'Mateo', 102),
(110, 'Nikki', 103),
(104, 'Paulo', 103),
(105, 'Richard', 103),
(120, 'Saanvi', 104),
(200, 'Shirley', 104),
(201, 'Sofía', 102),
(205, 'Zhang', 104);
Generated Table:
id name manager_id
100 Carlos
101 John 100
102 Jorge 101
103 Kwaku 101
110 Liu 101
106 Mateo 102
110 Nikki 103
104 Paulo 103
105 Richard 103
120 Saanvi 104
Recursive SQL to create the consolidated hierarchy path -
with recursive Hierarchy (id,name,manager_id,Path)
AS
(
SELECT t.id,t.name,t.manager_id, CAST(t.name AS varchar(max))
FROM schema_name.employee AS t
LEFT JOIN schema_name.employee AS t1
ON t1.id = t.manager_id
WHERE t1.id IS NULL
UNION ALL
SELECT t.id,t.name,t.manager_id, CAST(h.Path + '>' + t.name AS varchar(max))
FROM Hierarchy h
INNER JOIN schema_name.employee AS t
ON t.manager_id = h.id
)
SELECT id,name,Path
FROM Hierarchy
output :
id name path
100 Carlos Carlos
101 John Carlos>John
110 Liu Carlos>John>Liu
103 Kwaku Carlos>John>Kwaku
102 Jorge Carlos>John>Jorge
105 Richard Carlos>John>Kwaku>Richard
104 Paulo Carlos>John>Kwaku>Paulo
110 Nikki Carlos>John>Kwaku>Nikki
201 Sofía Carlos>John>Jorge>Sofía
106 Mateo Carlos>John>Jorge>Mateo

Find the most and the least used value from a MySQL table

I have a problem in finding the most and the least used value in the table.
The thing is that I have the values on two different columns and after I merge them together, I can't find the correct way of ordering them by the number of entries.
Firstly I have a table for each station
drop table if exists stations;
create table stations (
id_station int not null auto_increment,
st_name varchar (100),
primary key (id_station)
)auto_increment = 2000;
insert into stations values (null, 'Kobenhavn H'),
(null, 'Orestad'),
(null, 'Tarnby'),
(null, 'CPH Lufthavn');
select * from stations;
The table with the tickets contains all the information about the stations in use.
drop table if exists tickets;
create table tickets (
id_ticket int not null auto_increment,
starting_point varchar (100),
ending_point varchar (100),
id_train int,
departure_date date,
primary key (id_ticket),
foreign key (id_train) references trains (id_train)
)auto_increment = 100;
As you can see, the most used value is 2000 which is used 4 times; and the least used value is 2001 which is only used 1 time.
insert into tickets values ( null, 2000, 2003, 1, '2018.05.14'),
( null, 2000, 2003, 1, '2018.05.14'),
( null, 2003, 2000, 1, '2018.05.18'),
( null, 2002, 2000, 3, '2018.06.2 '),
( null, 2001, 2002, 3, '2018.06.4 ');
select * from tickets;
Here I must find the least and the most crowded station
I have tried to union all in order to get the two columns into one.
(select starting_point as 'All stations in use' from tickets)
union all
(select ending_point from tickets);
The part from above works perfectly, but the problem is that I don't know how to link it with the following part.
SELECT
stations.id_station AS 'All stations in use',
COUNT(*) AS 'Number of passengers'
FROM
(SELECT starting_point
FROM tickets
UNION ALL
SELECT ending_point from tickets) as Unix, stations
GROUP BY stations.id_station
ORDER BY COUNT(*);
What I wanted to obtain is:
2000 4
2003 3
2002 2
2001 1
Where 2000, 2003, 2002 and 2001 are the stations in use either from the first query or from the table stations
But what I get is:
2000 10
2001 10
2002 10
2003 10
I hoped that I could use something like where stations.id_station = Unix in the hope that I will solve the problem, but it won't work and I get the following error
Error Code: 1054. Unknown column 'Unix' in 'where clause'.
Can anyone help me please? I have been working on it for hours and I couldn't find any solution...
Kind regards,
Alin Chiver
You could use a union all
select point, count(*) from (
select starting_point point
from tickets
union all
select ending_point
from tickets) t
group by point

group by - with distinct results incl. count

Short question about the statement "group by" in mysql:
My current db structure looks like:
CREATE TABLE TableName
(
ID int primary key,
name varchar(255),
number varchar(255)
);
INSERT INTO TableName
(ID, name, number)
VALUES
(1, "Test 1", "100000"),
(2, "Apple", "200000"),
(3, "Test 1 beta", "100000"),
(4, "BLA", "300000"),
(5, "ABU", "400000"),
(6, "CBA", "700000"),
(7, "ABC", "600000"),
(8, "Orange - Test", "400000"),
(9, "ABC", "");
My current statement looks like:
SELECT name, number, count(*) as Anzahl
FROM TableName
group by name,number
with this statement the result looks like:
NAME NUMBER ANZAHL
ABC 1
Test 1 100000 2
Apple 200000 1
BLA 300000 1
ABU 400000 2
ABC 600000 1
CBA 700000 1
But the value "ABC" wouldn't merged.
the result should look like:
NAME NUMBER ANZAHL
Test 1 100000 2
Apple 200000 1
BLA 300000 1
ABU 400000 2
ABC 600000 2
CBA 700000 1
Any Ideas how it could work?
SQLFiddle:
http://sqlfiddle.com/#!2/dcbee/1
the solution must be performant for something like +1 000 000 rows
First of all IMHO, it's a bad design to store numbers into character column. Working with integers is faster than characters. Being said that, I assume all values in name column will be numbers. Here's is a query to avoid multiple ABC values
SELECT name,
SUM(convert(number, SIGNED INTEGER)) as number,
count(*) as Anzahl
FROM TableName
GROUP BY name ;
This is what I suggest (SQL Fiddle Link: http://sqlfiddle.com/#!2/c6f83b/5/0)
Like #Parag said, I strongly urge you to changed the table definition
Then the SQL is easy:
SELECT name, number, COUNT(*) AS anzahl
FROM tablename
WHERE number IS NOT NULL
GROUP BY name, number

Split functionality in mysql

I have a column empname in a table, the data stored is Lastname,Firstname.
For ex:
empname:
Martin,Ricky
Ford,Henry.
How to do i via select mysql query get the o/p as:
First name Last name
Ricky Martin
Henry Ford
Try this:
SELECT SUBSTRING_INDEX(empname, ',', -1) AS First_Name,
SUBSTRING_INDEX(empname, ',', 1) AS Last_Name
FROM table
Though I would prefer to do this on the application doing the output.