How to find a field with some specific value in another field in sql - sql

I have 2 columns MessageID and FlowStatusID.
I want to find MessageID's which have a FlowStatusID is one specific value with a special sequence.
For example I want to find MessageID's where the FlowStatusID contains the sequence of these numbers: 105,81,21
MessageID FlowStatusID
-------------------------
1 11
1 105
2 105
2 81
2 21
3 81
4 105
4 81
4 21
5 21
5 105
The result must be 2, 4

You don't mention the database type but I've found some other tickets which explain how to concatenate values from multiple records.
Postgress: Concatenate multiple result rows of one column into one, group by another column
Oracle : SQL Query to concatenate column values from multiple rows in Oracle
You can use this concatenated field in a condition with an equality match:
where myconcatresult = '21,81,105'
I don't know how this will perform :)

Try like this
select MessageIDfrom t group by MessageID having count(*) =3 ;
Or
select MessageID from (
select t.MessageID from t where FlowStatusID=21
union all
select t.MessageID from t where FlowStatusID=81
union all
select t.MessageID from t where FlowStatusID=105 )
as tt group by MessageID having count(*) =3

Related

How do I convert SQL data from one view to this other view in Postgres

I have table with data like this
id group order value
-------------------------
1 1 1 23
2 1 2 34
3 2 1 234
4 2 2 77
5 2 3 102
I want to insert into table so I have one row per group, with the value showing a string of comma-separated values orders based on the order.
id group value
----------------
1 1 23,34
2 2 234,77,102
How do I do this? I'm using Postgres 9.3
Postgres supports string_agg():
select row_number() over () as id, "group", string_agg(value, ',' order by "order")
from t
group by "group";
I would look at PostgreSQL's string_agg aggregate function.

Append 2 tables with identical fields

I have 2 tables with identical columns. Is there a way I can append them together. For example if my tables are:
Table 1:
ID Age
1 21
2 26
3 19
4 40
Table 2:
ID Age
6 29
8 40
10 35
I'd like the desired output to be:
ID Age
1 21
2 26
3 19
4 40
6 29
8 40
10 35
Is there a way I can append these 2 tables. Being new to SQL I tried using insert but couldn't do much about it.
Would be great if some one can help out
You can use a UNION ALL query:
SELECT ID, Age
FROM table1
UNION ALL
SELECT ID, Age
FROM table2
This will return all rows from each table in a single result. Here is a demo.
Use Union rather Union All if you want unique values based on two tables.
https://stackoverflow.com/a/49928/2745294
SELECT ID, Age
FROM table1
UNION
SELECT ID, Age
FROM table2

Writing a query for figuring out non-existent parent IDs in SQL

I have a table (Table1) wherein some columns reference another table (Table2) by id. it looks something like this:
Table 1
ID Column 1 Column 2 Column 3
3 15 16 0
4 19 0 0
5 21 22 23
6 0 0 0
7 25 26 0
8 27 0 0
Table 2
ID String
15 data
16 data
19 data
21 data
etc.
I am trying to write a query that returns results like this:
Table2ID Table1ID
15 3
16 3
19 4
21 5
22 5
23 5
25 7
etc.
There is no reference to any sort of parent in Table 2, so I'm trying to figure out the best way to query this. Any help would be much obliged, as my SQL experience is about less than two weeks worth.
You can use union (or union all) to combine the results of multiple queries. There are some rules you must follow in order to do this. First, each query must return the same number of columns. Next, each column does not necessarily need to return the same data type, but you can get unexpected errors if they are different data types so you are MUCH better of if each query returns the same data type for each column.
Just to be clear, when you have multiple columns, each query should return the same data type for the first column, and each query should return the same data type for the second column, but the data types for the first column do not need to match the data type of the second column.
Select Column1 As Table2ID, ID As Table1ID From Table1
Union All
Select Column2, ID From Table1
Union All
Select Column3, ID From Table1
SELECT Table2ID,t1.ID
FROM Table2 t2
JOIN Table1 t1
ON t2.Table1ID=t1.Col1 OR t2.Table1ID=t1.Col2 OR t2.Table1ID=t1.Col3

How to COUNT DISTINCT on more than one column

I have the following table.
group _id p_id version value
1 1 1 10
1 1 2 11
1 1 2 12
1 2 3 13
2 1 2 14
2 1 3 15
2 1 2 16
I would like to count on how many records for each group_id and how many distinct p_id + version for each group_id. I have following query
SELECT "group_id",count(*) , count(distinct "p_id","version")
FROM tbl
group by "group_id"
Aapparently, it' not going to work, as Oracle will give me error on COUNT
ORA-00909: invalid number of arguments
I know this can be done by subquery. However, is there any simple way to get same result? Considing the performance is important to me, as we have more than 500 million records in the table.
SQL Fiddle
I don't know if it's the best way, but I normally concatenate the two values, using a delimiter to enforce "distinctness", so they become one expression, which Oracle can handle with COUNT DISTINCT:
SELECT "group_id",count(*) , count(distinct "p_id" || '-' || "version")
FROM tbl
group by "group_id"

SQL query to find rows that aren't present in other tables

Here's what I'm trying to accomplish:
I've got two tables, call them first and second. They each have an ID column. They might have other columns but those aren't important. I have a third table, call it third. It contains two columns, ID and OTHERID. OTHERID references entries that may or may not exist in tables first and second.
I want to query third and look for rows who don't have an OTHERID column value that is found in either tables first or second. The goal is to delete those rows from table third.
Example:
first table:
ID
1
2
3
second table:
ID
6
7
8
third table
ID | OTHERID
21 1
22 2
23 3
24 4
25 5
26 6
27 7
28 8
In this case, I'd want to retrieve the IDs from third who don't have a matching ID in either table first or table second. I'd expect to get back the following IDs:
24
25
What I've tried:
I've done something this to get back the entries in third that aren't in first:
select t.* from third t where not exists (select * from first f where t.otherid = f.id);
and this will get me back the following rows:
ID | OTHERID
24 4
25 5
26 6
27 7
28 8
Similarly, I can get the ones that aren't in second:
select t.* from third t where not exists (select * from second s where t.otherid = s.id);
and I'll get:
ID | OTHERID
21 1
22 2
23 3
24 4
25 5
What I can't get my brain about this morning is how to combine the two queries together to get the intersection between the two results sets, so that just the rows with IDs 24 and 25 are returned. Those would be two rows I could remove since they are orphans.
How would you solve this? I think I'm on the right track but I'm just spinning at this point making no progress.
Maybe this :
SELECT third.*
FROM third
LEFT JOIN first ON third.otherID = first.id
LEFT JOIN second ON third.otherID = second.id
WHERE first.id IS NULL AND second.id IS NULL
Just use
select t.*
from third t
where
not exists (select * from first f where t.otherid = f.id)
and not exists (select * from second s where t.otherid = s.id)
SELECT t.ID
FROM third t
WHERE t.OTHERID NOT IN (
SELECT ID
FROM first
UNION
SELECT ID
FROM second
)