How to split a columns as separate table in SQL Server [duplicate] - sql-server

This question already has answers here:
Turning a Comma Separated string into individual rows
(16 answers)
Closed 5 months ago.
I am trying to split a column in my table as separate table in SQL Server. I currently have a table with data. I have a table with available courses for a program separated by semi column. I need to split this and keep it as two different tables as I need to search based on a course details.
Current table (program_details)
program_code
course_available
start_date
active
1
AB;01;ERl;KL09;324
18-Sep-2022
1
2
ER;02;EJl;DL09;414
14-Sep-2022
1
3
JK;CD;201;PL08;201
28-Sep-2022
1
4
FV;50;301;GL07;234
18-Oct-2022
1
I need to split this as two table for better searchability with course codes, I can write program for this or is there any easy way to achieve this using any functions of SQL Server?
Table program_details:
program_code
start_date
active
1
18-Sep-2022
1
2
14-Sep-2022
1
3
28-Sep-2022
1
4
18-Oct-2022
1
Table program_course_mapping:
mapping_id
pgm_code
course_id
1
1
AB
2
1
01
3
1
ER1
4
1
KL09
5
1
324
6
2
ER
7
2
02
8
2
EJ1
9
2
DL09
10
2
414

If you have SQL Server 2016,
SELECT program_code
,A.value FROM #T T
CROSS APPLY(SELECT * FROM STRING_SPLIT(T.Course_available,';')) A

Related

Extend row-level security to a bridging table

I am working on row level security in my database. I have two tables. Row based security is implemented on data_table and only returns rows that the user can see.
data_table:
data_id name role
-----------------------------
1 test USER
2 another ADMIN
3 yep USER
type_table:
type_id name
-----------------
1 this
2 is
3 a
4 type
EXECUTE AS USER = 'USER';
SELECT * FROM data_table;
returns rows 1 and 3 only. If you execute as ADMIN, all of the rows are returned. This is working properly in my database.
However, my issue is my bridging table.
data_type_table:
data_type_id data_id type_id
1 1 2
2 1 3
3 2 1
4 2 2
5 3 1
6 3 4
As of right now
EXECUTE AS USER = 'USER';
SELECT COUNT(data_type_id) FROM data_type_table;
returns 6 because it's looking at all 6 rows in the table. I'm trying to set it up in such a way that user USER will only see rows in data_type_table which are referencing rows where data_table.role = 'USER' (this means that the select count query would return 4). What would be the simplest way to implement something like this?
My data_table will more than likely contain hundreds of thousands of rows. Efficiency could become a problem here.

Sql Query to add values to the existing values in a Table [duplicate]

This question already has answers here:
LPAD in SQL Server 2008
(4 answers)
Closed 4 years ago.
Need to add "00" in-front of each row and the size of col1 is 3 i.e., (varchar(3))
I have data as below
col1
-----
1
02
003
4
05
I need to update the col1 values like prefix(001, 002, 003, 004, 005) as shown below.
col1
-----
001
002
003
004
005
I tried with SQL Server replicate function but I didn't get.
This is really a presentation layer requirement. I recommend just storing your col1 values an integers, and then generating the zero padded number using something like:
SELECT RIGHT('000' + CAST(col1 AS VARCHAR(3)), 3) AS col1_out
FROM yourTable;

How SQL queries may be optimized

I have a SQL Server table Top_Research_Areas that contains data like i.e.
aid res_category_id research_area Paper_Count
---------------------------------------------------------------
2937 33 markov chain 3
2937 33 markov decision process 1
2937 1 linear system 1
11120 29 aspect oriented prog 4
11120 1 graph cut 2
11120 1 optimization problem 2
12403 2 differential equation 7
12403 1 data structure 2
12403 1 problem solving 1
35786 1 complete graphs 11
35786 1 graph cut 10
35786 NULL NULL 2
49261 3 finite automata 6
49261 3 finite element 2
49261 14 database 2
78841 5 genetic programming 6
78841 23 active learning 2
78841 28 pattern matching 1
Now I want to select pid from another table i.e. sub_aminer_paper for the aid's in table Top_Research_Areas, whereas table sub_aminer_paper contains columns i.e. aid, pid, research_area, res_category_id and some more columns too.
Moreover Top_Research_Areas only contains records for top_3 research_area's whereas table sub_aminer_paper contains other than these records for aid's in Top_Research_Areas.
I have used this query i.e.
SELECT
aid, pid, research_area
FROM
sub_aminer_paper
WHERE
aid IN (2937, 11120)
AND research_area IN (SELECT
research_area
FROM
Top_Research_Areas
WHERE
aid IN (2937, 11120))
ORDER BY aid ASC
Now the issue is, when retrieving pid's from sub_aminer_paper by matching research_area's in both tables, it gives me output e.g. if I retrieve records for two aid's i.e. 2937 and 11120, it gives me the output as:
We can see that the Paper_Count for Top 2 aid's are 3+1+1+4+2+2 i.e. it should give 13 records, but it is giving 14 because of research_area i.e. optimization problem actually belongs to aid i.e. 11120 in table Top_Research_Areas but by using IN clause for matching research_area it is taking as a mixture of research_area's of both aid's, whereas I need 13 records in output instead of 14.
How can it be handled ?
Please help and thanks!
There probably is a paper on "optimization problem" for aid 2937 which isn't logged in top_research_Areas.
See id this helps : select from sub_aminer_paper where the combination of (aid,research_area) exists,
SELECT
sap.aid, sap.pid, sap.research_area
FROM
sub_aminer_paper sap
WHERE
sap.AID IN (2937, 11120) --- For indexing which I'm assuming this column has
AND EXISTS (SELECT 1 FROM Top_Research_Areas tra WHERE tra.aid = sap.aid and tra.research_area = sap.research_area and tra.aid in (2937,11120))

limit records in a cross join by customer effective date

In SQL Server 2012, I am tring to recreate a detailed sales transaction record from two tables that have historical summary information but can't seem to limit the records based on an customer start date. (Actually there are 3 tables, one with customer item categories and % of sales by category, but I'm not having trouble with that part of the cross join). Any help would be appreciated.
Imagine two table:
Customer
ID Customername Sales_Monthly Date_start
1 Acme $80,000.00 1/15/2012
2 Universal $50,000.00 1/3/2013
3 SuperMart $12,000.00 4/14/2013
Calendar
ID Date
1 1 /31/2014
2 2 /28/2014
3 3 /31/2014
4 4 /30/2014
5 5 /30/2014
6 6 /30/2014
7 7 /30/2014
8 8 /30/2014
9 9 /30/2014
10 10/30/2014
11 11/30/2014
12 12/30/2014
A simple cross join:
SELECT Calendar.Date, Customer.ID, Customer.Customername, Customer.Sales_2013
FROM Calendar, Customer
produces 36 entries as you'd expect (3 customers x 12 months)
However, I only want to produce entries 28 entries, where [Calendar.Date] > [Customer.Date_start]
I can't seem to find WHERE CLAUSE and any join type or subquery that will limit my records based on the Customer.Date_start field. Any suggestions on this?
If you're joining on a field in a cross join, it's no longer a cross join. Assuming your customer data in the question is incorrect, and you meant it to be 2014 on all the customer records, you can do the join like this.
SELECT *
FROM Customer a
JOIN Calendar b ON b.Date > a.Date_start
This produces 33 rows (12 for customer 1, 12 for customer 2, and 9 for customer 3, not 28 like you're expecting), but hopefully my answer will point you in the right direction.

Search Problem in SQL Server

I need to search in a table for items which have all of my desired values in a column i.e.
I have table :
ID : 1 2 3 3 2 2 2 1 1 3
VALUE : 5 6 5 3 6 7 2 1 9 0
I want to give a StoredProc a list of values for example ("6,7,2") and it returns me all IDs that have all the given values in this case it would only returns 2
If I wanted to search for those which at least have one of the values I know I could use "IN" but to have all the values i found nothing.
Thank you in advance
Afshin Arefi
In SQL Server 2008 you can use table value parameters.
These allow you to pass in a table of values to a stored procedure and treat it as any other table (use in sub-queries, joins etc).
In terms of the query - if you do use a table value parameter, you can query it for size (how many rows), use IN in conjunction with a GROUP BY on the ID field and a HAVING that counts the number of rows.

Resources