I have this table:
id type otherid
1 4 1234
2 5 1234
3 4 4321
As you can see there are 3 records, 2 of them belongs to otherid "1234" and got type of 4 and 5.
Last record belongs to otherid of "4321" and has only a type of 4.
I need to select all otherid that got only the type 4 and not the type5.
Example: after this select on that table the query shuould return only the record 3
Thanks
add1:
Please consider the TYPE can be any number from 1 up to 20.
I only need otherid that got type 4 but not type 5 ( except than that they can have any other type )
add2:
using mysql 5.1
This is kind of a workaround
SELECT * FROM (
SELECT GROUP_CONCAT('|',type,'|') type,other_id FROM table GROUP BY otherid
) t WHERE type LIKE '%|4|%' AND type NOT LIKE '%|5|%'
You could use a not exists subquery:
select distinct otherid
from YourTable as yt1
where yt1.type = 4
and not exists
(
select *
from YourTable as yt2
where yt1.otherid = yt2.otherid
and yt1.type <> yt2.type -- use this line for any difference
and yt2.type = 5 -- or this line to just exclude 5
)
Another way is by using a left join from where you exclude rows that have both type 4 and 5:
select a.*
from table1 a
left join table1 b on b.otherid = a.otherid and b.type = 5
where a.type = 4 and b.id is null
Related
I have two tables for which I am trying query in a certain way-
Table 1
ID
Cust Type
Status
1
A
Active
2
B
Active
3
A
Active
4
A
Active
5
B
Inactive
Table 2
ID
ID Type
ID Type Value
1
Type 1
1234
1
Type 2
2345
1
Type 3
3456
2
Type 1
4567
2
Type 3
5678
2
Type 5
6789
3
Type 1
7890
3
Type 4
8901
4
Type 5
9012
I am trying to get the result like this -
Result
ID Type
Count of Active Cust Type A
Type 1
2
Type 2
1
Type 3
1
Type 4
1
Type 5
0
I have tried different kinds of joins and group by but for whatever reason I do not see the results for the ID type which have a count of 0. So in the example above, I would not see Type 5.
Try this approach, valid in T-SQL (Sql Server)
In practice you build 2 temporary tables and left-join them so the type without counts would return a null value and you can COALESCE it at 0
SELECT TYPES.[ID Type], COALESCE(COUNTS.TYPE_COUNT, 0)
FROM
(SELECT DISTINCT [ID Type] FROM TABLE2) TYPES
LEFT JOIN
(SELECT T2.[ID Type], COUNT(*) as TYPE_COUNT
FROM TABLE2
JOIN TABLE1
ON TABLE2.ID = TABLE1.ID
WHERE TABLE1.Status = 'Active') COUNTS
ON TYPES.[ID Type] = COUNTS.[ID Type]
I did not try this so it may contains some syntax error, but my goal is to give you the idea
You need the left on the Table1, you want all of those values. You can put more than * in the count operator.
select Table1.ID, count(Table2.ID)
from Table1 left join Table2
on Table1.ID = Table2.ID
group by Table1.ID
You need a LEFT JOIN between tab2 and tab1, and a COUNT aggregation.
SELECT tab2.ID_Type, COUNT(tab1.ID) AS Count_of_Active_Cust_Type_A
FROM tab2
LEFT JOIN tab1 ON tab2.ID = tab1.ID AND tab1.Cust_Type = 'A'
GROUP BY tab2.ID_Type
Output:
ID_Type
Count of Active Cust Type A
Type 1
2
Type 2
1
Type 3
1
Type 4
1
Type 5
1
Check the MySQL demo and the SQLite demo.
Note: There's an active Cust Type A for Type 5 as well.
I have a table variable that looks like this:
id
V1
V2
1
A
1
1
A
2
1
B
3
2
C
2
2
A
3
3
A
1
3
A
2
3
B
2
4
C
3
5
A
2
I would like to select only the ids where at least one V2 = 3, to get something like this:
id
V1
V2
1
A
1
1
A
2
1
B
3
2
C
2
2
A
3
4
C
3
What is the SQL query to do this?
Select *
From yourtable
where id in (
select distinct id
from yourtable
where v2 = 3
)
Try:
select v.* from variable01 v where id in (select distinct id from variable01 where V2=3 ) ;
Working demo : http://sqlfiddle.com/#!9/dd7175/1
For this type of problem, I usually recommend exists because it optimizes better across more databases (with the right indexing):
select v.*
from variable v
where exists (select 1
from variable v2
where v2.id = v.id and
v2.v2 = 3
);
You can also express this quite well using in. But importantly, select distinct is not needed in the subquery:
select v.*
from variable v
where v.id in (select v2.id
from variable v2
where v2.v2 = 3
);
I have table with following schema and contains records-
id parent_id active
1 NULL Y
2 1 Y
3 1 N
4 NULL Y
5 4 N
6 NULL N
7 6 N
I need to write a SQL for following use case:
Need to find all records whose active not equals to Y and whose parent_id active equals to Y.
Example output of above should be as follows:
output should be-
id parent_id active
3 1 N
5 4 N
You could do it using self join as below:
SELECT *
FROM mytab t1 INNER JOIN mytab t2
ON t1.id = t2.parent_id
WHERE t1.active != 'Y'
AND t2.active = 'Y'
You can do this using self-join as following:
select t1.id,t1.parent_id,t1.active
from test t1 inner join test t2 on t1.parent_id=t2.id
where t1.active <> 'Y' and t2.active='Y';
Results can be seen here:
DB Fiddle Demo
use subquery 1st take all the id's who have active=Y then check with parent_id and active column
select * from tbale_name where
parent_id in (
select id from table_name where active='Y'
) and active='N'
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=4a450a50a2ea6c3f4e1a19e2657ae35d
id parent_id active
3 1 N
5 4 N
i am using MYSQL..
I have two tables:
TABLE 1 (TABLE NAME T1)
SL NAME
1 a
2 b
3 c
4 c
table 2 (table name T2)
SL NAME
1 a
2 c
3 c
4 c
Q1: how i count the total number of 'c' in both table?
Q2: which name is max occurrences in both table?
sl is primary key...
my query is:>
select count(*) from t1,t2
where t1.name=t2.name where t1.name='c';
but it showing 6
To count c in both tables you should use UNION, not JOIN.
Syntax:
SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
Doc:
http://dev.mysql.com/doc/refman/5.0/en/union.html
Edit:
I'll explain the query that you provided.
select count(*) from t1,t2 where t1.name=t2.name where t1.name='c';
First of all, you use WHERE clause twice which is a syntax error. Should be:
select count(*) from t1,t2 where t1.name=t2.name AND t1.name='c';
And this is the same that:
SELECT count(*) from t1
JOIN t2 ON t1.name=t2.name
WHERE t1.name='c';
You choose only rows with c value so these are the rows, that we will take under consideration:
TABLE 1 (TABLE NAME T1)
SL NAME
3 c
4 c
table 2 (table name T2)
SL NAME
2 c
3 c
4 c
Now, simple JOIN joins every row from table 1 to every row from table 2 (where condition is true of course)
So the result before counting is:
t1.SL t1.NAME t2.SL t2.NAME
3 c 2 c
4 c 3 c
3 c 4 c
4 c 2 c
3 c 3 c
4 c 4 c
This is 6 rows.
Answers for both of your questions.
SELECT name, count(*) as cnt
FROM(select t1.name from t1
union all
select name from t2) as tem
group by name
order by cnt DESC
This query will give you ranking of names ordered by occurrences.
To retrieve only c count, just add WHERE clause. To retrieve only the most occurring name set LIMIT clause to 1.
INSERT INTO #test
SELECT NAME FROM m_t1 WHERE NAME ='c'
UNION all
SELECT NAME FROM m_t2 WHERE NAME ='c'
SELECT count(*) FROM #test
I am trying to understand how to create a query to filter out some results based on an inner join.
Consider the following data:
formulation_batch
-----
id project_id name
1 1 F1.1
2 1 F1.2
3 1 F1.3
4 1 F1.all
formulation_batch_component
-----
id formulation_batch_id component_id
1 1 1
2 2 2
3 3 3
4 4 1
5 4 2
6 4 3
7 4 4
I would like to select all formulation_batch records with a project_id of 1, and has a formulation_batch_component with a component_id of 1 or 2. So I run the following query:
SELECT formulation_batch.*
FROM formulation_batch
INNER JOIN formulation_batch_component
ON formulation_batch.id = formulation_batch_component.formulation_batch_id
WHERE formulation_batch.project_id = 1
AND ((formulation_batch_component.component_id = 2
OR formulation_batch_component.component_id = 1 ))
However, this returns a duplicate entry:
1;"F1.1"
2;"F1.2"
4;"F1.all"
4;"F1.all"
Is there a way to modify this query so that I only get back the unique formulation_batch records which match the criteria?
EG:
1;"F1.1"
2;"F1.2"
4;"F1.all"
Thanks for your time!
In this case it is possible to apply the distinct before the join possibly making it more performant:
select fb.*
from
formulation_batch fb
inner join
(
select distinct formulationbatch_id
from formulation_batch_component
where component_id in (1, 2)
) fbc on fb.id = fbc.formulationbatch_id
where fb.project_id = 1
Notice how to use alias for the table names to make the query clearer. Also then in operator is very handy. The use of double quotes with those identifiers is not necessary.
One way would be to use distinct:
SELECT distinct "formulation_batch".*
FROM "formulation_batch"
INNER JOIN "formulation_batch_component"
ON "formulation_batch"."id" = "formulation_batch_component"."formulationBatch_id"
WHERE "formulation_batch"."project_id" = 1
AND (("formulation_batch_component"."component_id" = 2
OR "formulation_batch_component"."component_id" = 1 ))
I know the question asks how to prevent duplicates with inner join but could use an IN clause in the predicate.
SELECT "formulation_batch".*
FROM "formulation_batch" fb
ON "formulation_batch"."id" = "formulation_batch_component"."formulationBatch_id"
WHERE "formulation_batch"."project_id" = 1
AND fb.id IN (SELECT "formulation_batch"."id"
FROM formulation_batch_component
WHERE (("formulation_batch_component"."component_id" = 2
OR "formulation_batch_component"."component_id" = 1 ))