Comparing two tables and finding mismatches - sql

ive got two sql tables and i want to comepare them against eachother to find the ones that dont match.
i have something that works but for some reason missed out two records?
table flag_content contains:
- userid
- content_id
table topfive_order contains
- nid
- uid
i wish to find all records which topfive_order.nid doesnt exists in flag_content.content_id
my current query is:
select * from flag_content left join topfive_order topfive_order ON flag_content.content_id = topfive_order.nid WHERE topfive_order.nid is null
any tips or advice much welcome. im not too sure what im doing with left join.. so i assume that the couple of records which slip the net has something to do with that.

Turn the join around
SELECT *
FROM topfive_order topfive_order left join flag_content
ON flag_content.content_id = topfive_order.nid
WHERE flag_content.content_id IS NULL
To find rows from the topfive_order table that do not exist in the flag_content table, you need to put the topfive_order at the LEFT of the LEFT JOIN.
For more on various join types, see Wikipedia

Related

Relating Multiple Tables to One Table [SQL - Oracle 12c]

I'll try my best to pose this as a question, and not a "write my script" request- but finding it hard to phrase without using the working example.
To start, here's a relational diagram of what I'm working with;
**TABLE 1 - TABLE 2 are scalable, i.e there is a TABLE 4 - TABLE 5, TABLE -... etc, it's Tables, A/B/C that are constant.
Essentially, what I'm trying to do with this structure is match a certain value that only exists in TABLE 1 or 2 to TABLE C, where I'll pass that value to TABLE 1 or 2 and return the TABLE C value.
SELECT
TABLEC.CUSTOMID
FROM TABLE1
INNER JOIN TABLE2 ON TABLE1.TABLE2ENTITYKEY = TABLE2.ENTITYKEY
INNER JOIN TABLEA ON TABLEA.ENTITYKEY = TABLE2.TABLEAENTITYKEY
INNER JOIN TABLEB ON TABLEB.ENTITYKEY = TABLEA.TABLEBENTITYKEY
INNER JOIN TABLEC ON TABLEC.ENTITYKEY = TABLEB.TABLECENTITYKEY
WHERE TABLE1.USERENTITYKEY = /*ENTER_VALUE*/
OR
SELECT
TABLEC.CUSTOMID
FROM TABLE3
INNER JOIN TABLE4 ON TABLE3.TABLE4ENTITYKEY = TABLE4.ENTITYKEY
INNER JOIN TABLEA ON TABLEA.ENTITYKEY = TABLE4.TABLEAENTITYKEY
INNER JOIN TABLEB ON TABLEB.ENTITYKEY = TABLEA.TABLEBENTITYKEY
INNER JOIN TABLEC ON TABLEC.ENTITYKEY = TABLEB.TABLECENTITYKEY
WHERE TABLE3.USERENTITYKEY = /*ENTER_VALUE*/
Both of these work, and will work for my Tables 5/6, 7/8 etc - but that leaves me with multiple queries.
What I'd like to do is 'combine' these queries into one, where I'll pass my value to Tables 1/3/5 etc and return any values from C that link back to any of the source tables - it's not important that I know which source table the value in C links too, it's only important that it links to one of them.
Does anyone have any suggestions or examples I can use to see how this kind of script is formatted? I have played around with some things - but my SQL isn't that strong, so it's futile so far.
Thanks in advance, please comment if more information is required - and sorry in advance if the question is poorly asked!
-L
Not a full solution - but currently tying the two above queries together using UNION.

Issue with joins in a SQL query

SELECT
c.ConfigurationID AS RealflowID, c.companyname,
c.companyphone, c.ContactEmail, COUNT(k.caseid)
FROM
dbo.Configuration c
INNER JOIN
dbo.cases k ON k.SiteID = c.ConfigurationId
WHERE
EXISTS (SELECT * FROM dbo.RepairEstimates
WHERE caseid = k.caseid)
AND c.AccountStatus = 'Active'
AND c.domainid = 46
GROUP BY
c.configurationid,c.companyname, c.companyphone, c.ContactEmail
I have this query - I am using the configuration table to get the siteid of the cases in the cases table. And if the case exists in the repair estimates table pull the company details listed and get a count of how many cases are in the repair estimator table for that siteid.
I hope that is clear enough of a description.
But the issue here is the count is not correct with the data that is being pulled. Is there something I could do differently? Different join? Remove the exists add another join? I am not sure I have tried many different things.
Realized I was using the wrong table. The query was correct.

Access 2010 - Why does a query produce less results than the base table itself

I have created a query in Access 2010 that maps a number in the right table into the left table. when i run the query i get less results than the total number of records in the left table and i wonder why? it seems that some records are left out. Does somebody have a clue on what i am doing wrong?
edit: i cant post pictures so i´ll draw this here in a simplified way:
-table 1....-........-table 2...-..........-table 3... -
-number 1-.<->.-number 1-.........-xxxxxxxx...-
-xxxxxxxx...-.......-number 2-..<->..-number 2-
Query:
SELECT [2007].[Analyse (Nummer)],
[2007].[Analyse (Name)],
[2007].Faktura, BKPF2007.Referenz,
BSET.St
FROM BSET
INNER JOIN (2007 INNER JOIN BKPF2007 ON [2007].[Faktura] = BKPF2007.[Belegnr])
ON BSET.[Belegnr] = BKPF2007.[Referenz]
GROUP BY [2007].[Analyse (Nummer)],
[2007].[Analyse (Name)],
[2007].Faktura,
BKPF2007.Art,
BKPF2007.Referenz,
BSET.St;
That's one of the functions of JOIN - it does not show records that don't match. There are a few things I can suggest without seeing specifics.
Remove one of the joins, so your query only shows Table 1 and Table 2. Make sure you get the expected results before moving on to joining Table 3
Replace your joins with LEFT JOINS which show all records even if there is no match in the right-hand table. Even if this doesn't give you the solution you're hoping for, it may help you diagnose the problem.
This is the reason for your results being filtered:
INNER JOIN
You will need to make this a LEFT JOIN to keep all results where results do not exist on the right tables(s).

Group by in SQL Server giving wrong count

I have a query which works, goes like this:
Select
count(InsuranceOrderLine.AntallPotensiale) as potensiale,
COUNT(InsuranceOrderLine.AntallSolgt) as Solgt,
InsuranceProduct.Name,
InsuranceProductCategory.Name as Kategori
From
InsuranceOrderLine, InsuranceProduct, InsuranceProductCategory
where
InsuranceOrderLine.FKInsuranceProductId = InsuranceProduct.InsuranceProductID
and InsuranceProduct.FKInsuranceProductCategory = InsuranceProductCategory.InsuranceProductCategoryID
Group by
InsuranceProduct.name, InsuranceProductCategory.Name
This query over returns what I need, but when I try to add more table (InsuranceOrder) to be able to get the regardingUser column, then all the count values are way high.
Select
count(InsuranceOrderLine.AntallPotensiale) as Potensiale,
COUNT(InsuranceOrderLine.AntallSolgt) as Solgt,
InsuranceProduct.Name,
InsuranceProductCategory.Name as Kategori,
RegardingUser
From
InsuranceOrderLine, InsuranceProduct, InsuranceProductCategory, InsuranceSalesLead
where
InsuranceOrderLine.FKInsuranceProductId = InsuranceProduct.InsuranceProductID
and InsuranceProduct.FKInsuranceProductCategory = InsuranceProductCategory.InsuranceProductCategoryID
Group by
InsuranceProduct.name, InsuranceProductCategory.Name,RegardingUser
Thanks in advance
You're adding one more table to your FROM statement, but you don't specify any JOIN condition for that table - so your previous result set will do a FULL OUTER JOIN (cartesian product) with your new table! Of course you'll get duplication of data....
That's one of the reasons that I'm recommending never to use that old, legacy style JOIN - do not simply list a comma-separated bunch of tables in your FROM statement.
Always use the new ANSI standard JOIN syntax with INNER JOIN, LEFT OUTER JOIN and so on:
SELECT
count(iol.AntallPotensiale) as Potensiale,
COUNT(iol.AntallSolgt) as Solgt,
ip.Name,
ipc.Name as Kategori,
isl.RegardingUser
FROM
dbo.InsuranceOrderLine iol
INNER JOIN
dbo.InsuranceProduct ip ON iol.FKInsuranceProductId = ip.InsuranceProductID
INNER JOIN
dbo.InsuranceProductCategory ipc ON ip.FKInsuranceProductCategory = ipc.InsuranceProductCategoryID
INNER JOIN
dbo.InsuranceSalesLead isl ON ???????? -- JOIN condition missing here !!
When you do this, you first of all see right away that you're missing a JOIN condition here - how is this new table InsuranceSalesLead linked to any of the other tables already used in this SQL statement??
And secondly, your intent is much clearer, since the JOIN conditions linking the tables are where they belong - right with the JOIN - and don't clutter up your WHERE clauses ...
It looks like you added the table join which slightly multiplies count of rows - make sure, that you properly joining the table. And be careful with aggregate functions over several joined tables - joins very often lead to duplicates

How to get a related row if one (another) row exists?

I'm aware that this question's title might be a little bit inaccurate but I couldn't come up with anything better. Sorry.
I have to fetch 2 different fields, one is always there, the other isn't. That means I'm looking at a LEFT JOIN. Good so far.
But the row I want shown is not the row whose existence is uncertain.
I would like to do something like:
Show name and picture, but only show the picture if that name has a picture_id. Otherwise show nothing for the picture, but I still want the names regardless(left join).
I know this might be a little confusing but there's some clever guys out here so I guess somebody will understand it.
I tried some approaches but I couldn't quite say what I want in SQL.
P.S.: solutions specific to Oracle are good too.
------------------------------------------------------------------------------------------------------------------------------------
EDIT I've tried some queries but the main problem I found is that, inside the ON clause, I am only able to reference the last table mentioned, in other words:
There are four tables from which I'm retrieving data, but I can only mention the last (third table) inside the on clause of the LEFT JOIN(which is the 4th table). I'll describe the tables hopefully that'll help. Try not to delve too much on the names, because they are in Portuguese:
There are 4 tables. The fields I want to retrieve are :TB395.dsclaudo and TB397.dscrecomendacao, for a given TB392.nronip. The tables are as follows:
TB392(laudoid,nronip,codlaudo) // laudoid is PK, references TB395
TB395(codlaudo,dsclaudo) //codlaudo is PK
TB398(laudoid,codrecomendacao) //the pair laudoid,codrecomendacao is PK , references TB397
TB397(codrecomendacao,dscrecomendacao) // codrecomendacao is PK
Fields with the same name are foreign keys.
The problem is that there's no guarantee that, for a given laudoid,there will be one codrecomendacao. But, if there is, I want the dscrecomendacao field returned, that's what I don't know how to do. But even if there isn't a corresponding codrecomendacao for the laudoid, I still want the dsclaudo field, that's why I think a LEFT JOIN applies.
Sounds like you want your primary row source to be the join of TB392 and TB395; then you want an outer join to TB398, and when that gets a match, you want to lookup the corresponding value in TB397.
I would suggest coding the primary join as one inline view; the join between the two extra tables as a second inline view; and then doing an outer join between them. Something like:
SELECT ... FROM
(SELECT ... FROM TB392 JOIN TB395 ON ...) join1
LEFT JOIN
(SELECT ... FROM TB398 JOIN TB397 ON ...) join2
ON ...
It would be nice if you could specify what your tables are, which columns are on which tables, and what columns they join on. Its not clear if you have two tables or only one. I guess you have two tables because you are talking about a LEFT JOIN, and seem to imply that the join is on the name column. So you can use the NVL2 function to accomplish waht you want. So guessing what I can from your question, maybe something like:
SELECT T1.name
, NVL2( T2.picture_id, T1.picture, NULL )
FROM table1 T1
LEFT JOIN
table2 T2
ON T1.name = T2.name
If you only have one table, then its even simpler
SELECT T1.name
, NVL2( T1.picture_id, T1.picture, NULL )
FROM table1 T1
I think you need:
SELECT ...
FROM
TB395
JOIN
TB392
ON ...
LEFT JOIN --- this should be a LEFT JOIN
TB398
ON ...
LEFT JOIN --- and this as well, so the previous is not cancelled
TB397
ON ...
The details may be not accurate:
SELECT
a.dsclaudo
, b.laudoid
, c.codrecomendacao
, d.dscrecomendacao
FROM
TB395 a
JOIN
TB392 b
ON b.codlaudo = a.codlaudo
LEFT JOIN
TB398 c
ON c.laudoid = b.laudoid
LEFT JOIN
TB397 d
ON d.codrecomendacao = c.codrecomendacao
Create two views and then do your left join on the views. For example:
Create View view392_395
as
SELECT
t1.laudoid,
t1.nronip,
t1.codlaudo,
t2.dsclaudo
FROM TB392 t1
INNER JOIN TB395 t2
ON t1.codlaudo
= t2.codlaudo
Create View view398_397
as
SELECT
t1.laudoid,
t1.codrecomendacao,
t2.dscrecomendacao
FROM TB398 t1
INNER JOIN TB397 t2
ON t1.codrecomendacao
= t2.codrecomendacao
SELECT
v1.laudoid,
v1.nronip,
v1.codlaudo,
v1.dsclaudo,
v2.codrecomendacao,
v2.dscrecomendacao
FROM view392_395 v1
LEFT OUTER JOIN view398_397 v2
ON v1.laudoid
= v2.laudoid
In my opinion, views are always under used. Views are your friend. They can simplify some of the most complicated queries.