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
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.
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
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.
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)
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