package_id
item_id
1
1
1
2
2
1
3
1
3
2
How can I check in one query does
SELECT item_id
FROM table
where package_id =1`
is equal to
SELECT item_id
FROM table
where package_id =3
EXECPT or WHERE NOT IN
won't work if e.g.
SELECT EXISTS(
SELECT item_id
FROM table
where package_id=2
and item_id NOT IN (
SELECT item_id
FROM table
where package_id =3
)
)
I don't know what do you want to do with this query, but I think you need to review your approach.
Anyway, this query allows you to check if the result of query1 and the query 2 has the same
SELECT true AS isSame
FROM (SELECT item_id,
Sum(q1) AS q1Sum,
Sum(q2) AS q2Sum
FROM ((SELECT DISTINCT item_id,
1 AS q1,
0 AS q2
FROM packages
WHERE package_id = 1)
UNION ALL
(SELECT item_id,
0 AS q1,
1 AS q2
FROM packages
WHERE package_id = 2)) allItems) allItemsWithSum
WHERE q1sum = q2sum
I have a table like this:
Tb_Product_Options:
Product_Id Option_Id
1 5
1 7
2 3
3 9
3 6
Now I want to get all Product_Ids have not this values : '5,9'.
at this example my result must be: 2 (product_id)
You can aggregation :
select Product_Id
from table t
group by Product_Id
having sum ( Option_Id in (5,9) ) = 0;
If you want all columns then you can use NOT EXISTS :
select t.*
from table t
where not exists (select 1
from table t1
where t1.Product_Id = t.Product_Id and t1.Option_Id in (5,9)
);
In the old days, we would use an exclusion join:
SELECT DISTINCT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.stuff = x.stuff
AND y.other_stuff IN(some,values)
WHERE y.id IS NULL
This surely works:
select product_id
from Tb_Product_Options
where product_id not in (
select product_id
from Tb_Product_Options
where option_id in (5,9)
)
I have three tables asrecord of students:
record of courses:
Map student and course:
I want to get records from table std_course where student are as 1,2,3 using query
select course_id from std_course where std_id in (1,2,3) group by course_id
It returns me course_id as 1 but here std_id=4 also exist against course_id=1
I need to select course_id where std_id are only 1,2,3
You can use sum() and select case, std_id above 3 will be 0
select * from (
select sum(case when std_id in (1, 2, 3) then 1 else 0 end) tot
, course_id
from std_course
group by course_id) t1
where t1.tot <= 3
You can try this using join:
select * from std_course left outer join course on course.id= std_course.course_id where std_id <=3
The query that work for me after the changings in query Answered by #ϻᴇᴛᴀʟ is:
select * from ( select sum(case when std_id in (1,2,3) then 1 else -1 end) tot , course_id from std_course group by course_id) t1 where t1.tot = 3
After using UNION with two select queries, I'm getting following results
UserId Name Status
------ ------ --------
1 User1 Active
2 User2 Active
1 User1 InActive
3 User3 InActive
But the expected results is
UserId Name Status
---------------------
1 User1 Active
2 User2 Active
3 User3 InActive
Here what I need is, I want to group by column Id and get status as Active if any one result is active. How to form a SQL query for this?
Can anyone suggest query for any one of the following DB?
MSSQL
Oracle
MySQL
PostgreSQL
Edit:
This is the query I've tried in PostgreSQL
(SELECT DISTINCT User.Id,User.DisplayName,AppAccessToUsers.IsActive='1' AND User.IsActive='1' AS IsStatusActive
FROM Applications Left JOIN AppAccessToUsers ON (Applications.Id=AppAccessToUsers.ApplicationId)
Left JOIN User ON (AppAccessToUsers.UserId=User.Id) WHERE Applications.ClientId='e7e66c1b-b3b8-4ffb-844b-fc4840803265')
UNION
(SELECT DISTINCT User.Id,User.DisplayName,AppAccessToGroups.IsActive='1' AND Group.IsActive='1' AND UserGroup.IsActive='1' AND User.IsActive='1' AS IsStatusActive
FROM Applications Left JOIN AppAccessToGroups ON (Applications.Id=AppAccessToGroups.ApplicationId)
Left JOIN Group ON (AppAccessToGroups.GroupId=Group.Id) Left JOIN UserGroup ON (Group.Id=UserGroup.GroupId)
Left JOIN User ON (UserGroup.UserId=User.Id) WHERE Applications.ClientId='e7e66c1b-b3b8-4ffb-844b-fc4840803265')
Use this query,
SELECT UserId
,Name
,CASE WHEN min(status) = 'Active' THEN 'Active' ELSE 'InActive' END
FROM users GROUP BY UserId,Name
I would do the following, assuming a) your tables are called t1 and t2 (amend as appropriate for your actual table names) and b) the names for each userid in both tables are the same - ie. for userid = 1, both tables have the same name:
SELECT userid,
NAME,
MIN(status)
FROM (SELECT userid, NAME, status FROM t1
UNION ALL
SELECT userid, NAME, status FROM t2)
GROUP BY userid, NAME;
This works in Oracle, and I'm pretty sure it'll work in the other database platforms you mentioned.
N.B. I used MIN(status) since you appear to want a status of Active to override a status of Inactive, and A comes before I in the alphabet.
In Sql-server, you could use group by or Row_number like this
DECLARE #SampleData AS TABLE
(
UserId int,
Name varchar(20),
Status varchar(10)
)
INSERT INTO #SampleData
(
UserId,Name,Status
)
VALUES
(1,'User1', 'Active'),
(2,'User2', 'Active'),
(1,'User1', 'InActive'),
(3,'User3', 'InActive')
-- use row_number
;WITH temp AS
(
SELECT *, row_number() OVER(PARTITION BY sd.UserId ORDER BY sd.Status ) AS Rn
FROM #SampleData sd
)
SELECT t.UserId, t.Name, t.Status
FROM temp t WHERE t.Rn = 1
--or use group by
SELECT sd.UserId, sd.Name, min(sd.Status) AS status
FROM #SampleData sd
GROUP BY sd.UserId, sd.Name
Results:
UserId Name Status
1 User1 Active
2 User2 Active
3 User3 InActive
In case of MS Sql Server you can try row_number
;with cte as (
select top 1 with ties * from
( select * from #youruser
union all
select * from #youruser) a
order by row_number() over (partition by userid order by [status] desc)
) select * from cte where status = 'Active'
select your_table.* from your_table
inner join (
select UserId, min(Status) as st from your_table
group by UserId
) t
on your_table.UserId = t.UserId and your_table.Status = t.st
Note: if same UserId can have same Status more than 1 times, then this returns duplicated results.
;With cte (UserId, Name,Status)
AS
(
SELECT 1,'User1','Active' Union all
SELECT 2,'User2','Active' Union all
SELECT 1,'User1','InActive' Union all
SELECT 3,'User3','InActive'
)
SELECT UserId
,NAME
,[Status]
FROM (
SELECT *
,ROW_NUMBER() OVER (
PARTITION BY UserId
,NAME ORDER BY STATUS
) AS Seq
FROM cte
) dt
WHERE dt.Seq = 1
OutPut
UserId Name Status
-----------------------
1 User1 Active
2 User2 Active
3 User3 InActive
for postgres you can use CASE and bool_or, eg:
t=# with a(i,n,b) as (
values (1,'a','active'), (1,'a','inactive'), (2,'b','inactive'), (2,'b','inactive')
)
select i,n,case when bool_or(b = 'active') then 'active' else 'inactive' end
from a
group by i,n
;
i | n | case
---+---+----------
1 | a | active
2 | b | inactive
(2 rows)
Another approach:
Note : Group by is to remove duplicate
select
A.USERID, A.NAME,A.STATUS
from TAB_1 A
LEFT JOIN
(SELECT * FROM TAB_1 WHERE STATUS='Active') B
ON A.USERID=B.USERID
WHERE
( B.STATUS IS NULL OR A.STATUS=B.STATUS)
GROUP BY A.USERID, A.NAME,A.STATUS
ORDER BY A.USERID
;
We have a table with two columns - art_id and cat_id.
We need to select rows WHERE cat_id = 12, 13, 15
I tried to do something:
SELECT art_id
FROM table
WHERE cat_id IN (12,13,15)
GROUP BY art_id
HAVING COUNT(cat_id) > 2
but this selection also select art_id = 4 AND 9.
Expected Output:
art_id = 1 and 7
Assuming you do not have know beforehand the art_ids, perhaps this?
SELECT art_id, GROUP_CONCAT(cat_id SEPARATOR ',') as concatenated
FROM table
GROUP BY art_id
HAVING concatenated = '12,13,15'
If the sequence in each group can be different. E.g. 13,12,15 then you'll need to sort the combinations too.
SELECT art_id,
GROUP_CONCAT(DISTINCT cat_id ORDER BY cat_id ASC SEPARATOR ',') AS concatenated
FROM table
GROUP BY art_id
HAVING concatenated = '12,13,15'
I hope this will work for you
SELECT art_id
FROM table
WHERE cat_id IN (12,13,15)
AND (art_id = 4 OR art_id = 7)
GROUP BY art_id
HAVING COUNT(cat_id) > 2
You can try this, but it works only if you haven't art_id, cat_id repetition eg: it doesn't work if you add in your sample data INSERT INTO T1 VALUES (9,15) two times
SELECT DISTINCT T1.art_id
FROM T1
INNER JOIN (SELECT art_id, COUNT(*) AS RC
FROM T1
WHERE CAT_ID IN (12,13,15)
GROUP BY art_id) X ON T1.art_id = X.art_id
WHERE X.RC>2
Output:
art_id
-----------
1
7