Joined tables single row with desired results - sql

First of all, I know that this is a case of a bad design, but I am just wondering how can I get single sql result from the jointure with the desired infos.
So it's a simple exemple, 2 tables connected with ids:
TableA TableB
id code id tableA_id (FK) start end
---- ------- ---- ---------------- ------- ------
1 codeA 1 2 NY null
2 codeB 2 2 null LA
So line 2 in TableA has 2 corresponding lines in TableB.
Desired result:
tableA_code tableB_start tableB_end
------------- -------------- ------------
codeB NY LA
So in the result in need to group the 2 lines from the table B into one line and eliminate the null values.

The query :
select A.code, B1.start, B2.end
from TableB B1, TableB B2, TableA A
where B1.tableA_id = B2.tableA_id
and B1.tableA_id = A.id
and B1.start is not null and B2.end is not null

Let me know if this works for you
SELECT A.code,
MAX(B.STRT) STRT,
MAX(B.END)
END
FROM
(SELECT 1 AS A_ID,'CODE A' AS CODE FROM DUAL
UNION ALL
SELECT 2 AS A_ID,'CODE B' AS CODE FROM DUAL
)A,
(SELECT 1 AS B_ID,2 AS A_ID,'NY' STRT, NULL AS END FROM DUAL
UNION ALL
SELECT 2 AS B_ID,2 AS A_ID, NULL STRT, 'LA' AS END FROM DUAL
)B
WHERE A.A_ID = B.A_ID
GROUP BY A.code;

Related

SQL instruction that shows if there is a value in a another table

I have two files, header and detail. In the detail file, there is a key field to find or join header. I need to count the number of header rows that have a detail record. I want to know the number of records with field1 = 'A' only, and the number of header rows that have a record with field1 = 'A' or = 'B'.
It doesn't work with a Join or a CASE and subselect query.
Here is a simplified example:
Table AA (header) and table BB (detail). Table AA has field HeadId.
Table BB has three fields: HeadId, DetId and Data. HeadId is used to join with header table. Value of field Data can be equal A or B. An AA row can have more rows on BB.
I need to know how many rows in AA have BB only rows with value of Data = A and how many have both A and B. I need to do this with only a SQL query.
Please can you help me?
I used union for this and only the 'BB' table for counting
SELECT COUNT(*) as count, 'Only A' as type
FROM BB b
WHERE NOT EXISTS (SELECT headId FROM BB WHERE Data != 'A' AND headId = b.headId)
GROUP BY headId, data
UNION
SELECT COUNT(*), 'A and B'
FROM BB b1
JOIN BB b2 ON b1.headId = b2.headId AND b1.id != b2.id AND b1.data != b2.data
WHERE b1.data IN ('A', 'B') AND b2.data IN ('A', 'B')
GROUP BY b1.headId
There are multiple ways to accomplish the same thing. Basing my code off of Joakim's answer a bit, this one works for me:
SELECT headId
FROM HEADER;
HEADID
------
1
2
3
4
select headId,
detailId,
someData
from Detail
;
HEADID DETAILID SOMEDATA
------ ----------- --------
1 1 A
2 1 A
2 2 B
3 1 X
4 1 A
SELECT 'Only A' AS TYPE,
COUNT(*) AS COUNT
FROM HEADER H
WHERE EXISTS (SELECT 1 FROM DETAIL D
WHERE D.HEADID = H.HEADID AND SOMEDATA = 'A')
AND NOT EXISTS (SELECT 1 FROM DETAIL D
WHERE D.HEADID = H.HEADID AND SOMEDATA <> 'A')
GROUP BY 'Only A'
UNION
SELECT 'Both A and B' AS TYPE,
COUNT(*) AS COUNT
FROM HEADER H
WHERE EXISTS (SELECT 1 FROM DETAIL D
WHERE D.HEADID = H.HEADID AND SOMEDATA = 'A')
AND EXISTS (SELECT 1 FROM DETAIL D
WHERE D.HEADID = H.HEADID AND SOMEDATA = 'B')
GROUP BY 'Both A and B'
;
TYPE COUNT
------------ -----------
Both A and B 1
Only A 2
Hope that helps!

Join Table and fill null column with return table value

i have two tables as below
TableA
A_id name
---- ----
123 Test1
124 Test2
125 Test3
126 Test4
TableB
B_id fk_A_id value type_id
---- ------- ----- -------
1 123 op1 1
2 123 hello 2
3 123 abc 3
4 126 op2 1
5 126 hello 2
6 126 def 3
i use query to join both table
select TableA.A_id as id, TableA.name as name, TBL2.type_name as type_name
from TableA
full join (
select fk_A_id, value as type_name
from TableB
where type_id = 2
)TBL2 on TableA.A_id = TBL2.fk_A_id
the return result would be
id name type_name
-- ---- ---------
123 Test1 hello
124 Test2
125 Test3
126 Test4 hello
my question is how i fill the null column with 'hello' as well which is the return result from TableB, the type_id = '2' will have similar string across that TableB
I think you want a left join, like this:
select a.A_id as id, a.name as name, b.type_name as type_name
from TableA a left join
TableB b
on a.A_id = b.fk_A_id and b.type_id = 2;
There is no need for a subquery and the full join is overkill.
If you want the NULL value to also be hello, use coalesce():
select a.A_id as id, a.name as name,
coalesce(b.type_name, 'hello') as type_name
from TableA a left join
TableB b
on a.A_id = b.fk_A_id and b.type_id = 2;

INSERT rows by Comparing Two Tables

I have two tables like this:
ID Name Value
----------------------
1 Book1 A
2 Book2 B
3 Book3 C
Name
----------------------
Book4
Book5
I'm trying to write query to insert rows in the first table so it becomes:
ID Name Value
----------------------
1 Book1 A
2 Book2 B
3 Book3 C
1 Book4 NULL
2 Book4 NULL
3 Book4 NULL
1 Book5 NULL
2 Book5 NULL
3 Book5 NULL
I can't get it to work with this query:
SELECT a.ID,
b.Name,
a.Value
FROM table1 a
LEFT JOIN (SELECT Name FROM table2) b ON a.Name = b.Name
I also tried CROSS JOIN but still couldn't quite get it. Any help will be appreciated.
For this case I will name TableA your first table and TableB the one with only names. But next time try to provide some meaningfull names.
INSERT INTO TableA
SELECT A.ID, B.Name, Null
FROM
(
SELECT DISTINCT ID
FROM TableA
) A, TableB B

Sql Join Table , Part Of Select Data Condition

I have two table table A and table B.
Table A Contain Id, Number, Time , Value1
Table B Contain Id, Data, Value2
Example of the Record on Table A:
Id Number Tried Value1
------- ---------- --------- ---------
1 123 23 5
2 124 23 6
3 1254 23 7
Example of the Record on Table B:
Id Data Value2
------ --------- -------
1 123,23 6
2 122,21 5
3 1254,23 7
My Purpose to Add Value 1 and Value 2 together by join condition of the table B Data with table A Number and Tried to match the record.
Example :
Id (Value1 + Value2)
------- -----------------
1 11
3 14
My Query:
select a.Id , a.Value1+ b.Value2
from a
join b on substring(b.Data,1,3) = a.Number and substring(b.Data,5,2) = a.Tried
I had tried substring but the value of Data Record Length is different compare on Id 1 and 3 and current of Query Result only show Id 1. Is there other way to join with 1 column field that split into 2 kind of value which take out ',' to join 2 field on table a?
Check if this query would help, in Oracle
select a.Id , (a.Value1+ b.Value2)
from a, b
where a.id = b.id and b.Data = (a.Number || ',' || a.Tried);
EDIT: Based on #Joachim Isaksson suggestion:
select a.Id ,b.Id (a.Value1+ b.Value2)
from a, b
where b.Data = (a.Number || ',' || a.Tried);
You can use the following query.
select A.Id, (A.Value1 + B.Value2) [Value1 + Value2] from tblA A
inner join tblB B on A.Number = SUBSTRING(B.Data, 1, charindex(',', B.Data, 1) - 1)
And A.Tried = SUBSTRING(B.Data, charindex(',', B.Data, 1) + 1, Len(A.Tried))
This I have tried in SQL Server.
Query of Nishanthi Grashia can also be converted in SQL Server. You just need to replace || with +

SQL Select Statement issue - returning rows conditionally on a 2nd table

I could really use some help with the following SQL Select statement scenario:
I need to select all rows from a table conditionally depending on whether a userID has already entered data into a second table with the same ID.
Example:
Select all rows from TABLE A for idNumber where idNumber not in
TABLE B
but for each idNumber that IS in TABLE B, still return row unless a
specific userID is in that row in TABLE B.
TABLE A
========
idNumber|type|Date
1 A 01/01/01
2 A 01/01/01
3 B 01/01/01
4 B 01/01/01
5 B 01/01/01
TABLE B
========
idNumber|type|userID
1 A 0000
3 B 0000
4 B 1111
userID to exclude records for = 1111
SQL Query should return:
idNumber|type|Date
1 A 01/01/01
2 A 01/01/01
3 B 01/01/01
5 B 01/01/01
Apologies for the long winded post but i hope it makes sense.
Many thanks in advance,
ukjezza.!!
Select idNumber, type, Date
From TableA
Where Not Exists (
Select 1
From TableB
Where TableB.idNumber = TableA.idNumber
And TableB.userID = 1111
)
Another choice:
Select TableA.idNumber, TableA.type, TableA.Date
From TableA
Left Join TableB
On TableB.idNumber = TableA.idNumber
And TableB.userId = 1111
Where TableB.idNumber Is Null
Looks like a LEFT JOIN and COALESCE could take care of it:
SELECT a.*
FROM TableA as a
LEFT JOIN TableB as b
ON a.idNumber = b.idNumber
WHERE COALESCE(b.userID, -1) != 1111
select A.*
from TableA as A
left outer join TableB as B
on A.idNumber = B.idNumber
where B.idNumber is null or
B.userID <> '1111'