Find the rows that has the same column - sql

I want to know how to do the following in SQL :
SELECT *
FROM table_A
WHERE id IN(:myValues)
AND other_colum has the same value
For example, if i've a conversation table(iduser,idconversation), I want SQL query that returns some of Ids that have the same conversation id. It should return
35;105
37;105
35;106
37;106
With 35,37 the idUsers and 105,106 the conversations they have in common.
To go further, i work with Doctrine and PostegreSQL, and the table that I want to query is generated (many to many relation) but i've difficulty to integrate sub-query.
**public function getAllCommonConversationByUserId($ids)
{
return $this->createQueryBuilder('c')
->select('c.id')
->innerJoin('c.idUser', 'recievedConversation')
->where('recievedConversation IN (:ids)')
->andWhere('$qb->expr()->eq("SELECT id FROM table GROUP BY(id) HAVING COUNT(*) >1")')
->setParameter(':ids', $ids)
->getQuery()
->getResult();
}**

Just:
SELECT *
FROM table_A
WHERE idconversation in ('105','106') and iduser in ('35','37')
UPDATE:
Are you saying if the idconversation is duplicate? (showing multiple times?)
If so:
Select *
From table
where idconversation in
(
Select idconversation
From table
group by (idconversation)
Having count(*) >1
)
--where iduser in ('35','37')

Try to do this:
select id, conversation
from [your table name]
where
conversation in (
select conversation
from [your table name]
where id in (35)
)
It return all of the participants of the conversation with user id = 35
If you have duplicates in your table, please add distinct to select statement.

You can get the conversations using group by and having:
SELECT conversationid
FROM table_A
WHERE userid in (35, 37)
GROUP BY userid
HAVING count(distinct userid) = 2;
If you want the original rows, you can join back to the original table.

Related

SQL Create a duplicate row for each additional count

I have a table with a many to many relationship, in which I need to make a 1 to 1 without modifying the schema. Here is the pseudo code:
Reports {
Id INT,
Description NVARCHAR(256),
ReportFields...
}
ScheduledReports {
ScheduledReportId INT
ReportId INT (FK)
Frequency INT
}
When I run this query:
SELECT [ReportID], COUNT(*) as NumberOfReports
FROM [ScheduledReports]
GROUP BY ReportId
HAVING COUNT(*) > 1
I get return the results of all the reports who have duplicates.
ReportId, NumberOfReports
1, 2
2, 4
Foreach additional report (e.g NumberOfReports -1).
I need to create a duplicate row in the Reports table. However I'm having trouble on figuring out how to turn the count into a join (since I don't want to use cursors).
Here is my query:
INSERT INTO Reports (Description)
SELECT Description
FROM Reports
WHERE ReportId IN (SELECT [ReportID]
FROM [ScheduledReports]
GROUP BY ReportId
HAVING COUNT(*) > 1)
How do I Join the ReportRow on itself for Count(*) -1 times?
The below query should get you a sequencing of the schedules per unique report. You can then use the sequencing > 1 to determine which values will need to be inserted to your report table. Output of this select should probably be cached, since it will
Indicate which rows need to be added to your Reports by their current ID
Can be used to later update the referenced ReportID in your schedules table
SELECT *
FROM (
SELECT Reports.Id
,ScheduledReportId
,ROW_NUMBER() OVER (
PARTITION BY ReportId
ORDER BY ScheduledReportId
) AS [Sequencing]
FROM Reports
INNER JOIN ScheduledReports on ScheduledReports.ReportId = Reports.Id
WHERE ReportId IN (SELECT [ReportID]
FROM [ScheduledReports]
GROUP BY ReportId
HAVING COUNT(*) > 1)) AS SequencedReportAndSchedules

How to pulls related values in PostgreSQL?

Here is my problem.
I have two tables like user and customer. Users can be related to some customer(s).
For example, I have a user who relates to two customers, and the other user relates to three customers, etc.
This is my code that creating tables and inserting values;
create table tbl_user
(
id int,
username varchar(100),
relatedcustom_id int
)
create table tbl_custom
(
id int,
name varchar(100)
)
insert into tbl_custom values(1,'john'),
(2,'adam'),
(3,'steve'),
(4,'marliyn'),
(5,'coco'),
(6,'George');
insert into tbl_user values (1,'cst_moose',1),
(1,'cst_moose',2),
(2,'cst_moose',3),
(3,'cst_kevin',2),
(4,'cst_kevin',5),
(5,'cst_donald',1),
(6,'cst_donald',2),
(7,'cst_donald',4),
(8,'cst_henry',1),
(9,'cst_henry',6),
(10,'cst_michel',1),
(11,'cst_michel',2);
I want to pull the user name(s) that relates to customers that id is 1 and 2.
Here is my select code;
select username from tbl_user where exists (select 1 from tbl_custom
where
id in(1,2))
except
select username from tbl_user where exists (select 1 from tbl_custom
where
id not in(1,2))
But this query demonstrates nothing.
The other select code ;
select username from tbl_user where relatedcustom_id in (1,2)
except
select username from tbl_user where relatedcustom_id not in (1,2)
This query shows like this;
username
--------
cst_michel
What I want to do is a Select - As - From with the following fields
username
--------
cst_michel
cst_moose
cst_donald
I want to pull the user name(s) that relates to customers that id is 1 and 2.
You can use aggregation and having:
select username
from tbl_user
group by username
having sum( (relatedcustom_id = 1)::int ) > 0 and
sum( (relatedcustom_id = 2)::int ) > 0 and
sum( (relatedcustom_id not in (1, 2)::int ) ) = 0;
One of the possible solution is to use arrays:
select username
from tbl_user
where relatedcustom_id in (1,2) -- to filter out unrelated data
group by username
having array[1,2] <# array_agg(relatedcustom_id);
-- or '{1,2}' <# array_agg(relatedcustom_id);

Hive Query with a large WHERE Condition

I am writing a HIVE query to pull about 2,000 unique keys from a table.
I keep getting this error - java.lang.StackOverflowError
My query is basic but looks like this:
SELECT * FROM table WHERE (Id = 1 or Id = 2 or Id = 3 Id = 4)
my WHERE clause goes all the way up to 2000 unique id's and I receive the error above. Does anyone know of a more efficient way to do this or get this query to work?
Thanks!
You may use the SPLIT and EXPLODE to convert the comma separated string to rows and then use IN or EXISTS.
using IN
SELECT * FROM yourtable t WHERE
t.ID IN
(
SELECT
explode(split('1,2,3,4,5,6,1998,1999,2000',',')) as id
) ;
Using EXISTS
SELECT * FROM yourtable t WHERE
EXISTS
(
SELECT 1 FROM (
SELECT
explode(split('1,2,3,4,5,6,1998,1999,2000',',')) as id
) s
WHERE s.id = t.id
);
Make use of the Between clause instead of specifying all unique ids:
SELECT ID FROM table WHERE ID BETWEEN 1 AND 2000 GROUP BY ID;
i you can create a table for these IDs and after use the condition of exist in the new table to get only your specific IDs

Postgresql - Insert when select return something

Is it possible to run select query, check if row exist and then insert some values? I would like to do that in one query. I think about SELECT .. CASE .. THEN, for example:
SELECT user_id, CASE when user_id > 0 then (INSERT INTO another_table ...) ELSE return 0 END
FROM users WHERE user_id = 10
Now I'm able to do that with 2 queries, first do SELECT and second INSERT values (if first query return something).
Thanks!
in general the construct is:
INSERT INTO another_table
SELECT value1,value2..etc
where exists (SELECT user_id FROM users WHERE user_id = 10)
or in this particular case:
INSERT INTO another_table
SELECT value1,value2..etc
FROM users WHERE user_id = 10
If no such user, no rows will be selected and so inserted

Reuse of select query result oracle

I've got following query
SELECT ID FROM MARMELADES mrm
where not exists
(SELECT 1 FROM TOYS toys
WHERE mrm.ID = toys.ID
AND mrm.INGREDIENT = toys.INGREDIENT
AND mrm.BOX_TYPE = 2)
AND mrm.BOX_TYPE = 2
It returns almost 400+ results of id, for example [12, 33, 45, ... , 3405]
Now, i want to remove all ids that are from that list everywhere from my database. this is not only MARMELADES and TOYS. Also, i have for example 35+ tables where i can have this id).
I would be happy if this query could extract in some functions like ALL_UNNEEDED_IDS so i can use it like this:
DELETE FROM ANOTHER_TABLE_1 WHERE ID IN ( ALL_UNNEEDED_IDS )
DELETE FROM ANOTHER_TABLE_2 WHERE ID IN ( ALL_UNNEEDED_IDS )
DELETE FROM ANOTHER_TABLE_3 WHERE ID IN ( ALL_UNNEEDED_IDS )
DELETE FROM ANOTHER_TABLE_4 WHERE ID IN ( ALL_UNNEEDED_IDS )
...
DELETE FROM ANOTHER_TABLE_35 WHERE ID IN ( ALL_UNNEEDED_IDS )
It is possible to do it in oracle to reuse such results?
Use the first query within your subsequent queries. IE:
DELETE FROM ANOTHER_TABLE_1 WHERE ID IN (
SELECT ID FROM MARMELADES mrm
where not exists
(SELECT 1 FROM TOYS toys
WHERE mrm.ID = toys.ID
AND mrm.INGREDIENT = toys.INGREDIENT
AND mrm.BOX_TYPE = 2)
AND mrm.BOX_TYPE = 2
);
When you get to the toys and marmelades tables, you'll need a temporary holder table as #Gordon suggests.