Can this be made into a sql join - sql

I want to find where mydata has a Q value but not at least one corresponding d value. How would I solve using a left join or right join?
If it can not be solved using joins, please give some insight into why not, because I am not seeing it.
Below is the solution that I found which works against data provided.
SELECT distinct tablea.mykey
FROM mytest as tablea
where tablea.mydata = 'Q'
and tablea.mykey not in (select distinct tableb.mykey
FROM mytest as tableb
where tableb.mydata = 'd')
mykey mydata
7 d
5 Q
5 d
5 d
6 Q
6 d
6 a
9 Q
9 a
9 a

You can use an outer join and then select only the non-matches
SELECT distinct tablea.mykey
FROM mytest as a
left join mytest as b on a.mykey = b.mykey
and b.mydata = 'd'
where a.mydata = 'Q'
and b.mykey is null

Related

What is outer apply in SQL?

select *
from Kosten_Test a
left join T_Pflege_Parameter pv on pv.Parameterbezeichnung = 'Dummy' and pv.Parametereigenschaft = 'Dummy3'
left join T_Pflege_Parameter pp on pp.Parameterbezeichnung = 'Dummy2' and pp.Parametereigenschaft = a.Herkunft
outer apply( select max(VarianteID) as VarianteID, MerkmalTyp, MerkmalWert
from Test2
where MerkmalTyp = pv.Parameterwert and MerkmalWert = sku
group by MerkmalWert, MerkmalTyp
union
select max(VarianteID) as VarianteID, MerkmalTyp, MerkmalWert
from Testvariante_ASIN_SKU
where MerkmalTyp = pv.Parameterwert and MerkmalWert = a.asin
group by MerkmalWert, MerkmalTyp
) vm
left join (select distinct bundleid from T_Archiv_BundleKomponente) bk on bk.BundleID = vm.VarianteID
Because of the Outer Apply Statement i become always double results. Who can help?
Outer apply is not like a LEFT JOIN. It will apply all the values from the OUTER APPLY Statement to the data joined against.
If your query without the outer apply returns 5 rows and the outer apply query returns 5 rows then the resulting dataset would contain 25 records with each record from the outer apply joined to each row of the other data.
Often times data would be condensed down using aggregations of the values returned from the outer apply query grouped inside of the main query.
Example -
Q1
----
A
B
C
OuterApplyQuery
-----------------
1
2
3
SELECT * FROM Q1 OUTER APPLY (SELECT * FROM OuterApplyQuery) AS X
Result
---------
A 1
A 2
A 3
B 1
B 2
B 3
C 1
C 2
C 3

Count the number of rows returned in SQL ORACLE

I have a little problem, my query look like this
select count(A.toto)
from B
inner join C
on B.tata = C.tata
inner join A
on C.tutu = A.tutu
group by A.toto, A.zaza, A.zozo;
and my result look like this :
1
2
1
6
7
4
1
1
1
But I want only the number of rows, for this example, the value that I would like to have is 9.
But I don't know how I can have this value...
Thank you in advance !!
You can use count(distinct). Unfortunately, Oracle doesn't support count(distinct) with multiple arguments, so a typical method is just to concatenate the value together:
select count(distinct A.toto || ':' || A.zaza || ':' || A.zozo)
from B inner join
C
on B.tata = C.tata inner join
A
on C.tutu = A.tutu;
This assumes that. the column values don't have the separator character (or at least in such a way that the concatenation is the same for rows with different key values).
An alternative method is to use a subquery:
select count(*)
from (select 1
from B inner join
C
on B.tata = C.tata inner join
A
on C.tutu = A.tutu
group by A.toto, A.zaza, A.zozo
) abc

sql function case returns more than one row

Going to use this query as a subquery, the problem is it returns many rows of duplicates. Tried to use COUNT() instead of exists, but it still returns a multiple answer.
Every table can only contain one record of superRef.
The below query I`ll use in SELECT col_a, [the CASE] From MyTable
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = myTable.sysno AND A_specAttr = 'value')
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo WHERE C_superRef = myTable.sysno AND b_type = 2)
THEN 2
ELSE (SELECT C_intType FROM C
WHERE C_superRef = myTable.sysno)
END
FROM A, B, C
result:
3
3
3
3
3
3...
What if you did this? Because Im guessing you are getting an implicit full outer join A X B X C then running the case statement for each row in that result set.
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = 1000001838012)
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo AND C_superRef = 1000001838012 )
THEN 2
ELSE (SELECT C_type FROM C
WHERE C_superRef = 1000001838012)
END
FROM ( SELECT COUNT(*) FROM A ) --This is a hack but should work in ANSI sql.
--Your milage my vary with different RDBMS flavors.
DUAL is what I needed, thanks to Thorsten Kettner
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = 1000001838012)
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo AND C_superRef = 1000001838012 )
THEN 2
ELSE (SELECT C_type FROM C
WHERE C_superRef = 1000001838012)
END
FROM DUAL

Join two select statements

Could somebody please, give me some advice on how to join the following two select statements:
SELECT TOP 200 *
FROM dbo.Creation_LimitsAndExclusions WITH (nolock)
WHERE LeagueCodeID = 37
and
select *
from dbo.Creation_Markets with (nolock)
where ClassID = 9 and IsParentMatch = 1
Thanks in advance.
I've no idea what the key is, but if the key was CreationID in both tables a join would look like this:
SELECT TOP 200 *
FROM dbo.Creation_LimitsAndExclusions WITH (nolock)
LEFT JOIN dbo.Creation_Markets ON Creation_LimitsAndExclusions.CreationID = Creation_Markets.CreationID
WHERE Creation_LimitsAndExclusions.LeagueCodeID = 37
AND Creation_Markets.ClassID = 9 and Creation_Markets.IsParentMatch = 1
Also don't know what the key is but I would add a cm.creationId IS NOT NULL condition in the where clause to ensure that we aren't taking rows from Creation_LimitsAndExclusions that are not matched
SELECT TOP 200 *
FROM dbo.Creation_LimitsAndExclusions cle WITH (nolock)
LEFT JOIN dbo.Creation_Markets cm
ON cle.CreationID = cm.CreationID
WHERE cle.LeagueCodeID = 37
AND cm.ClassID = 9
AND cm.IsParentMatch = 1
AND cm.creationID IS NOT NULL

Using REGEXP_LIKE in old style join

I have PL/SQL query with old style joins (with using (+) ). And now I need to add left joined table with REGEXP_LIKE clause. How can I make this?
In ANSI-style the query look like this:
select
*
from
deals d
left join
auctions a on a.session_code = d.session_code
left join
auction_history ah on ah.auction_code = a.auction_code and
REGEXP_LIKE(ah.auction_code, '^[A-Z]+')
where
trunc(d.operday) = trunc(sysdate)
And in old style I want to get something like this:
select
*
from
deals d,
auctions a,
auction_history ah,
where
trunc(d.operday) = trunc(sysdate) and
d.session_code = a.session_code (+) and
(a.auction_code = ah.auction_code (+) and
REGEXP_LIKE(ah.auction_code, '^[A-Z]+'))
But it doesn't return deals which session_code is null.
Thanks in advance!
REGEXP_LIKE is treated as a regular function regarding legacy joins. Here's an example:
SQL> WITH main_table AS
2 (SELECT 1 ID FROM dual UNION ALL
3 SELECT 2 FROM dual),
4 lookup_table AS
5 (SELECT 1 ID, 'txt' txt FROM dual UNION ALL
6 SELECT 2 ID, '999' txt FROM dual)
7 SELECT m.id, l.txt
8 FROM main_table m, lookup_table l
9 WHERE m.id = l.id(+)
10 AND REGEXP_LIKE(l.txt(+), '^[A-Z]+');
ID TXT
---------- ---
1 txt
2
Still, I would advise against using old-style joins in recent editions.