Search Problem in SQL Server - 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.

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.

How to configure a table column in TSQL that works as a sequence depending on the values of another two columns?

I have a table that looks like this:
ID A B Count
-----------------
1 abc 0 1
2 abc 0 2
3 abc 1 1
4 xyz 1 1
5 xyz 1 2
6 xyz 1 3
7 abc 1 2
8 abc 0 3
The "Count" column is incremented by one in the next insertion depending on the value of fields "A" and "B". so for example, if the next record I want to insert is:
ID A B Count
-----------------
abc 0
The value of count will be 4.
I have been trying to find documentation about this, but I'm still quite lost in the MS SQL world! There must be a way to configure the "Count" column as a sequence dependent on the other two columns. My alternative would be to select all the records with A=abc and B=0, get the maximum "Count", and do +1 in the latest one, but I suspect there must be another way related to properly defining the Count column when creating the table.
The first question is: Why do you need this?
There is ROW_NUMBER() which will - provided the correct PARTITION BY in the OVER() clause - do this for you:
DECLARE #tbl TABLE(ID INT,A VARCHAR(10),B INT);
INSERT INTO #tbl VALUES
(1,'abc',0)
,(2,'abc',0)
,(3,'abc',1)
,(4,'xyz',1)
,(5,'xyz',1)
,(6,'xyz',1)
,(7,'abc',1)
,(8,'abc',0);
SELECT *
,ROW_NUMBER() OVER(PARTITION BY A,B ORDER BY ID)
FROM #tbl
ORDER BY ID;
The problem is: What happens if a row is changed or deleted?
If you write this values into a persistant column and one row is removed physically, you'll have a gap. Okay, one can live with this... But if a value in A is changed from abc to xyz (same applies to B of course) the whole approach breaks.
If you still want to write this into a column you can use the ROW_NUMBER() from above to fill these values initially and a TRIGGER to set the next value with your SELECT MAX()+1 approach for new rows.
If the set of combinations is limited you might create a SEQUENCE (needs v2012+) for each.
But - to be honest - the whole issue smells a bit.

Inserting one table's complete column data to a particular column in another table in SQL Server

Inserting one table's complete column data to a particular column in another table in SQL SERVER
I have two tables i.e AuditCalendar, ScheduleAudit
Audit Calendar has two columns Taskid, TaskTypeId
Schedule Audit has two columns Scheduleid, Taskid
Audit Calendar looks like this
Taskid (Auto increment) TaskTypeId
-------------------------------------
1 1
2 2
3 3
4 1
5 1
But I want Taskid column data from Audit Calendar table based on TaskTypeId .Columns
After completion of query, the ScheduleAudit table should look like this
Scheuleid (AutoIncrement) Taskid
-------------------------------------
1 1
2 1
3 1
I have to run this query seems to look like a error
Subquery returns more than one value
Query is:
INSERT INTO ScheduleAudit(TaskId)
VALUES ((SELECT TaskId FROM AuditCalendar Where TaskTypeId = 1))
Please can you suggest how I can do this approach I am new to SQL Server but someone says that use cursors.... I am really confused last 1 week on words. And also search google but not get it now...Please can you give me any one valuable suggestions.
insert ... values is supposed to insert a single row. So what you have in the parentheses is supposed to produce a single row, or else it would fail.
There's no need to use insert ... values, when you can use insert ... select:
INSERT INTO ScheduleAudit(TaskId)
SELECT TaskId FROM AuditCalendar Where TaskTypeId=1
...however, that would produce
1 1
2 4
3 5
I'm not sure I understand the logic behind producing your example output.

How to (or Can I) select a random value from the Postgresql database excluding some particular records?

Is it possible to randomly select a record from the database excluding some records with particular status?
For eg,
For example, I have a table for storing employee details.
id employeename employeestatus
1 ab 1
2 cd 1
3 ef 2
4 gh 1
5 ij 1
What I want from the query is to fetch a single random record whose status is not 2. Is it possible to do so? The database I'm using is PostgreSQL 8.4.15.
TRY This
SELECT *
FROM employee
WHERE employeestatus != 2
ORDER BY RANDOM()
LIMIT 1
Try this other question on the same topic
Best way to select random rows PostgreSQL
It's tricker than you think (to do efficiently)

writing stored procedure to select values from one column based on input parameter refering to another column of the same table

I have a table with two columns projectIDS and ServiceIDS. Each project will have a set of services. Now I have to write a procedure to get common services for a list of projectIDs I pass as a parameter.
i.e., suppose i have
PID SID
--- ---
1 1
1 2
1 3
2 1
2 2
3 1
3 3
Now if i pass PIDs (1,2,3) as input parameter i should get SID = 1 as output since it is common for all projects.
thank you
I think what you are trying to do is find records where a whole set is matched.
Lets assume you have this set in a table, link this to your source table, this excludes PIDs that aren't in your set.
Then count the number of matches for each SID. If the number of PIDs for a SID equals the number of PIDs in your set then you have a match.
SELECT Sid
FROM MyTable
GROUP BY Sid
HAVING Count(DISTINCT Pid) = 3

Resources