Same column name from two tables satisfying two conditions - sql

I need some quick help on SQL. This is basic for most I am sure.
I want to select orderId in both tables merged that satisfies status = 1.
Please find example of the two table tb1 and tb2 here:
tb1
orderId status
---------------
001 0
003 1
005 1
007 1
...
tb2
orderId status
----------------
002 1
008 1
004 0

Use this query:
SELECT
tb1.OrderId,
tb1.Status
FROM
tb1
WHERE
tb1.status = 1
UNION
SELECT
tb2.OrderId,
tb2.Status
FROM
tb2
WHERE
tb2.status = 1;

You can use UNION ALL.
Your query would be:
SELECT *
FROM (
SELECT *
FROM tb1
UNION ALL
SELECT *
FROM tb2
) a
WHERE STATUS = 1

Related

SQL select units with condition of another column

I have this
ID
Product
001
A
001
B
001
C
002
A
002
A
002
D
003
G
003
D
003
C
004
G
004
D
004
R
and I wand ID list if they don't have product C...so:
002
You can apply the set difference between all ids and all ids with a "c" with the standard way of doing it: using the NOT IN operator in the WHERE clause.
SELECT DISTINCT ID
FROM tab
WHERE id NOT IN (SELECT ID FROM tab WHERE Product = 'C')
Consider below query:
SELECT DISTINCT ID FROM (
SELECT *, COUNTIF(product = 'C') OVER (PARTITION BY ID) AS cnt_C
FROM sample_table
) WHERE cnt_C = 0
output:
There are multiple ways of doing this, but I think a very readable way is to use NOT EXISTS.
SELECT DISTINCT id
FROM mytable t1
WHERE NOT EXISTS (SELECT 1 FROM mytable t2 WHERE t2.id = t1.id AND t2.Product = 'C')
The WHERE clause checks that there is no row with product C and the same id. The DISTINCT ensures you don't get multiples of the same id returned.
I am not sure but I think you just need a normal where
SELECT * FROM table_name WHERE product != product_name
*insert the table name in the place of Table_name and product name in the place of product_name
select distinct
id
from
your_table_name
where
product <> 'C';
This will return you list of ID's that don't have product C

JOIN to get items without value in other table gives multiple results

I have two tables like this:
Table1
ObjectName
ObjectId
Status
Name 1
001
OK
Name 2
002
OK
Name 3
003
Wait
Name 4
004
Wait
Table2
ObjectId
ObjectColor
001
Red
001
Blue
002
Magenta
002
Cyan
003
Blue
003
Green
004
Orange
004
Cyan
Now, I want to query ObjectName of any item with status OK in Table1 and without the color blue in Table2.
The nearest I can come is this:
SELECT
Table1.ObjectName
FROM
Table1
LEFT JOIN Table2 ON Table2.ObjectId = Table1.ObjectId
WHERE
Table1.Status = 'OK'
AND Table2.ObjectColor <> 'Blue'
This results in:
ObjectName
Name 1
Name 2
Name 2
I understand why this doesn't work. But what would be the correct approach?
I expect to only get one instance of Name 2 from this query.
Thanks!
Why join at all? You want data from table1, so select from table1. You want to exclude certain rows, which is why you have a WHERE clause. One restriction is Status = 'OK', the other is that NOT EXISTS 'Blue' for the object in table2.
select objectname
from table1
where status = 'OK'
and not exists
(
select null
from table2
where table2.objectid = table1.objectid
and table2.objectcolor = 'Blue'
);
As there are no nulls involved, you can do the same with the simpler NOT IN:
select objectname
from table1
where status = 'OK'
and objectid not in (select objectid from table2 where objectcolor = 'Blue');
You can use distinct if you just want the unique ObjectName
SELECT
Table1.ObjectName
FROM
Table1
WHERE
Table1.Status = 'OK'
and not exists
(select 1 from Table2 where ObjectColor = 'Blue' and table2.objectid=table1.objectid)
SELECT
Table1.ObjectName
FROM
Table1
JOIN
(
SELECT ObjectId FROM TABLE2 WHERE ObjectColor<>'BLUE'
)X ON Table1.ObjectId=X.OBJECTID
WHERE Table1.Status = 'OK'
You can use below query
At first I have selected the IDs from Table2 whose not have any entry belong to BLUE (SubQuery). After that I just join this result with Table1
SELECT * FROM Table1
Inner Join
(
SELECT Objectid from Table2
group By Objectid
Having SUM(Case when ObjectColor ='Blue' Then 1 else 0 end)=0
) t2
on Table1.Objectid=t2.Objectid
And Table1.status='OK'

Recursive sql select from unlimited nodes

I have this table in sql:
TopicID Code Name ParentID
------- ---- ---- --------
1 001 Parent1 0
2 001 Childp1 1
3 002 Parent2 0
4 001 Childp2 3
5 001 Childp21 4
.
.
etc
Now I want to
1.get sql select which retrives me the last node? (which I did by following line)
select * from accounting.topics where topicid not in(select parentid from accounting.topics)
and the result is:
TopicID Code Name ParentID | newcolumn
------- ---- ---- -------- | ---------
2 001 Childp1 1 | 001001
5 001 Childp21 4 | 002001001
2.Important one is to show the concat of code from first to last node of each row in above result,like newcolumn in above,Actually I can't produce the newcolumn ?
*notice that the nodes level are unlimited.
This could be done relatively easy with recursive common table expressions:
with cte as (
select
T1.TopicID, T1.Code, T1.Name, T1.ParentID,
T1.ParentID as NewParentID,
cast(T1.Code as nvarchar(max)) as NewColumn
from Table1 as T1
where not exists (select * from Table1 as T2 where T2.ParentID = T1.TopicID)
union all
select
c.TopicID, c.Code, c.Name, c.ParentID,
T1.ParentID as NewParentID,
c.NewColumn + cast(T1.Code as nvarchar(max)) as NewColumn
from cte as c
inner join Table1 as T1 on T1.TopicID = c.NewParentID
)
select
c.TopicID, c.Code, c.Name, c.ParentID, c.NewColumn
from cte as c
where c.NewParentID = 0
sql fiddle demo

SQL Join with multiple row condition in second table

I have a question on SQL join which involve multiple condition in second joined table. Below is the table details
Table 1
pId status keyVal
---- ------- ------
100 1 45
101 1 46
Table 2
pId mode modeVal
100 2 5
100 3 6
101 2 7
101 3 8
I have above two tables and I am trying to join based on below condition to get pId's
pId's which has keyVal = 45 and status = 1 joined with table2 which has mode = 2 and modeVal 5 and mode =3 and modeVal = 6
the result I am expecting is to return pid = 100
Can you please help me with a join query ?
One way is to use GROUP BY with HAVING to count that the number of rows found is 2, of which 2 are matching the condition;
WITH cte AS (SELECT DISTINCT * FROM Table2)
SELECT t1."pId"
FROM Table1 t1 JOIN cte t2 ON t1."pId" = t2."pId"
WHERE t1."status" = 1 AND t1."keyVal" = 45
GROUP BY t1."pId"
HAVING SUM(
CASE WHEN t2."mode"=2 AND t2."modeVal"=5 OR t2."mode"=3 AND t2."modeVal"=6
THEN 1 END) = 2 AND COUNT(*)=2
If the values in t2 are already distinct, you can just remove the cte and select directly from Table2.
An SQLfiddle to test with.
SELECT columns
FROM table1 a, table2 B
WHERE a.pid = B.pid
AND a.keyval = 45
AND a.status = 1
AND (
(B.mode = 2 AND B.modeval = 5)
OR
(B.mode = 3 AND B.modeval = 6)
)
Below query should work for you perfectly
select distinct table1.pid FROM table1 JOIN table2
on table1.pid = table2.pid
WHERE table2.modeValue IN (5,6) AND table2.mode IN (2,3) AND table1.keyVal=45 and table1.status=1;

SQL query help

Sorry for posting this question again. I rephrased my question a little bit.
I am trying to write a query to return rows from Table-A where multiple rows found in Table-B with STATUS = 1 for each CID column from Table-A.
So in this example CID 100 has two records found in Table-B and STATUS = 1. So I want to write a query to return this row from Table-A. I know this is a weird table design. Please help.
Here are the tables with sample data.
Table-A
-----------------------------------------
AID Name CID
---------------------------------------
10 test1 100
12 test1 100
13 test2 101
14 test2 101
15 test3 102
Table-B
------------------------------------
bID AID status
-----------------------------------
1 10 1
2 12 1
3 14 1
4 15 1
Try this query:
SELECT TableA.CID
FROM TableA
JOIN TableB ON TableA.AID = TableB.AID
WHERE TableB.status = 1
GROUP BY TableA.CID
HAVING COUNT(*) > 1
It returns 100 for your example data.
Something like this?
select aid,
status
from (select aid,
count(*) as cnt
from tableA
group by aid) as aggregated
left join tableB on tableB.aid = aggregated.aid
where aggregated.cnt > 1
If your using SQL:
WITH tableBView AS
(
SELECT AID AS xxxAID
FROM [Table-B]
WHERE status = 1
GROUP BY AID
HAVING COUNT(*) > 0
)
SELECT *
FROM [Table-A]
WHERE EXISTS (SELECT * FROM tableBView WHERE xxxAID = AID)
SELECT *
FROM Table-A a
WHERE a.CID IN
(
SELECT a.CID FROM Table-A a JOIN Table-B b USING (AID)
GROUP BY a.CID
WHERE b.status = 1
HAVING count(*) > 1
)
This is a very verbose way to do it.
Selects all columns from Table-A on rows where AID match between Table-A and Table-B and more than one row with the same CID exists in Table-A:
(Btw, I wouldn't use "-" in your table/column names. Use "_" instead.)
select
derived_table.AID,
derived_table.Name,
derived_table.CID
from
(select
table_A.AID,
table_A.Name,
table_A.CID,
count(table_A.CID) c
from
Table_A
inner join Table_B on (Table_A.AID = table_B.AID)
group by table_A.CID
) derived_table
where
c > 1