TSQL: Query items which their max version is have state Failed [duplicate] - sql-server

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed last year.
I have an SQL database with below rules:
There are items with same name but different versions.
Status of item production is stored inside a column State.
The structure of table log inside test database is like below:
id
Name
Ver
State
1
A
1
OK
2
B
1
Failed
3
C
1
OK
4
D
1
OK
5
A
2
OK
6
B
2
OK
7
C
2
Failed
8
D
2
OK
9
A
3
Failed
According to our production rules, the last version made from an item should have state OK (not Failed). So I want a query to grab list of unacceptable items with below constraints:
Name of items which their last version state is 'Failed'
In my sample data, the query should return A and C since Max version of A is 3 but its state is 'Failed' and max version of C is 2 but its state is Failed.
B and D are OK since their last version is 2 and the state of the version 2 for these items is OK.
How can I write query to bring list of items which their last version is failed (and not OK)?

Ah, yes, super rusty. Yet, you can definitely do this with a subquery:
SELECT mytable.name, mytable.ver, mytable.state
from
(SELECT NAME, VER
FROM TABLE GROUP BY NAME
HAVING VER = max(VER)) subq
INNER JOIN table on subq.name = mytable.name and subq.ver = mytable.ver
WHERE mytable.STATE = 'failed'
This is not a performant answer.

Related

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

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

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.

SQLite Row_Num/ID

I have a SQLite database that I'm trying to use data from, basically there are multiple sensors writing to the database. And I need to join one row to the proceeding row to calculate the value difference for that time period. But the only catch is the ROWID field in the database can't be used to join on anymore since there are more sensors beginning to write to the database.
In SQL Server it would be easy to use Row_Number and partition by sensor. I found this topic: How to use ROW_NUMBER in sqlite and implemented the suggestion:
select id, value ,
(select count(*) from data b where a.id >= b.id and b.value='yes') as cnt
from data a where a.value='yes';
It works but is very slow. Is there anything simple I'm missing? I've tried to join on the time difference possibly, create a view. Just at wits end! Thanks for any ideas!
Here is sample data:
ROWID - SensorID - Time - Value
1 2 1-1-2015 245
2 3 1-1-2015 4456
3 1 1-1-2015 52
4 2 2-1-2015 325
5 1 2-1-2015 76
6 3 2-1-2015 5154
I just need to join row 6 with row 2 and row 3 with row 5 and so forth based on the sensorID.
The subquery can be sped up with an index with the correct structure.
In this case, the column with the equality comparison must come first, and the one with unequality, second:
CREATE INDEX xxx ON MyTable(SensorID, Time);

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)

simple recursive query

I have 2 tables as follows (sample data shown):
TableName: A
ID Type
1 Bug
2 Requirement
3 Task
4 Specification
5 Bug
6 Specification
7 Production Issue
8 Production Issue
9 Bug
10 Task
Tablename: B
ID RelatedID
1 2
1 7
5 8
5 4
9 6
9 10
I want to fetch all the bugs that have atleast one related production issue or bugs that have no related production issue.
Expected output will be as shown below (since these are the bugs with at least one related production issue)
output
1
5
Aliases are the way to go here
SELECT pri.Type AS 'Primary Type', rel.Type AS 'Related Type'
FROM A AS pri
INNER JOIN B ON B.ID = pri.ID
INNER JOIN A AS rel ON B.RelatedID = rel.ID
WHERE pri.Type = 'Bug' AND rel.Type = 'Production Issue;

Resources